fix: keep generation progress out of chat history

This commit is contained in:
2026-04-26 22:44:44 +08:00
parent ea550de6a1
commit b7a507044f
8 changed files with 74 additions and 67 deletions

View File

@@ -43,6 +43,7 @@ RPG 在点击生成草稿后会离开聊天工作区,进入独立的生成进
- 玩法特有的生成进度只通过 `beforeExecuteAction``onActionError` 这类回调接入compile action 发起前切到独立生成页并初始化进度,失败时把进度置为 failed。
- compile action 成功后继续由通用控制器切到结果页,页面层只补齐生成资产数量、拼图操作记录、作品架与广场刷新等玩法差异。
- 离开玩法流程时,先清理运行态与生成进度态,再交给通用控制器恢复创作中心,避免流式回复和进度状态在下一次创作中残留。
- 生成进度页的阶段文本、资产完成文本、草稿写回文本只属于进度读模型和结果页状态,不属于 Agent 聊天历史。后端 compile / asset action 不再追加 `action_result` 聊天消息;前端聊天气泡只展示 `kind === "chat" | "summary" | "warning"` 的消息,历史会话中已经存在的 `action_result` 只作为兼容数据保留,不再渲染。
## 验收点
@@ -50,4 +51,5 @@ RPG 在点击生成草稿后会离开聊天工作区,进入独立的生成进
- 生成中可看到独立进度页,且进度步骤随 action 完成逐步推进。
- 拼图结果页打开时已有正式图;大鱼结果页打开时主图、动作和背景资产均已写入 `assetSlots`
- 前端点击生成草稿时不串行调用多个资产 action多阶段业务编排收敛在 `server-rs`
- 返回 Agent 工作区后,聊天区不出现“拼图结果页草稿已生成。”“本级主图已正式生成,可在结果页继续预览。”这类生成进度页状态消息。
- 不新增 server-node 依赖,不复活 legacy public 静态资产路径。

View File

@@ -112,13 +112,6 @@ pub(crate) fn generate_big_fish_asset_tx(
updated_at,
};
replace_big_fish_session(ctx, &session, next_session);
append_big_fish_system_message(
ctx,
&input.session_id,
format!("big-fish-message-asset-{}", input.generated_at_micros),
reply,
input.generated_at_micros,
);
get_big_fish_session_tx(
ctx,

View File

@@ -538,13 +538,6 @@ pub(crate) fn compile_big_fish_draft_tx(
updated_at: compiled_at,
};
replace_big_fish_session(ctx, &session, next_session);
append_big_fish_system_message(
ctx,
&input.session_id,
format!("big-fish-message-compile-{}", input.compiled_at_micros),
reply,
input.compiled_at_micros,
);
get_big_fish_session_tx(
ctx,
@@ -682,32 +675,6 @@ pub(crate) fn replace_big_fish_session(
ctx.db.big_fish_creation_session().insert(next);
}
pub(crate) fn append_big_fish_system_message(
ctx: &ReducerContext,
session_id: &str,
message_id: String,
text: String,
created_at_micros: i64,
) {
if ctx
.db
.big_fish_agent_message()
.message_id()
.find(&message_id)
.is_some()
{
return;
}
ctx.db.big_fish_agent_message().insert(BigFishAgentMessage {
message_id,
session_id: session_id.to_string(),
role: BigFishAgentMessageRole::Assistant,
kind: BigFishAgentMessageKind::ActionResult,
text,
created_at: Timestamp::from_micros_since_unix_epoch(created_at_micros),
});
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -659,12 +659,6 @@ fn compile_puzzle_agent_draft_tx(
updated_at: compiled_at,
},
);
append_system_message(
ctx,
&row.session_id,
input.compiled_at_micros,
"拼图结果页草稿已生成。",
)?;
get_puzzle_agent_session_tx(
ctx,
PuzzleAgentSessionGetInput {
@@ -1260,25 +1254,6 @@ fn build_puzzle_suggested_actions(
}
}
fn append_system_message(
ctx: &TxContext,
session_id: &str,
created_at_micros: i64,
text: &str,
) -> Result<(), String> {
let message_id = format!("{session_id}-system-{created_at_micros}");
ensure_message_missing(ctx, &message_id)?;
ctx.db.puzzle_agent_message().insert(PuzzleAgentMessageRow {
message_id,
session_id: session_id.to_string(),
role: PuzzleAgentMessageRole::Assistant,
kind: PuzzleAgentMessageKind::ActionResult,
text: text.to_string(),
created_at: Timestamp::from_micros_since_unix_epoch(created_at_micros),
});
Ok(())
}
fn ensure_session_missing(ctx: &TxContext, session_id: &str) -> Result<(), String> {
if ctx
.db

View File

@@ -103,3 +103,31 @@ test('big fish workspace hides keyword fill before two turns', () => {
expect(screen.queryByRole('button', { name: '补充剩余设定' })).toBeNull();
});
test('big fish workspace does not render progress action messages as chat bubbles', () => {
render(
<BigFishAgentWorkspace
session={{
...baseSession,
messages: [
...baseSession.messages,
{
id: 'message-action-result-1',
role: 'assistant',
kind: 'action_result',
text: '本级主图已正式生成,可在结果页继续预览。',
createdAt: '2026-04-24T10:01:00.000Z',
},
],
}}
onBack={() => {}}
onSubmitMessage={() => {}}
onExecuteAction={() => {}}
/>,
);
expect(screen.getByText('爽点和生态已经清楚,继续补剩余关键词。')).toBeTruthy();
expect(
screen.queryByText('本级主图已正式生成,可在结果页继续预览。'),
).toBeNull();
});

View File

@@ -52,6 +52,14 @@ function mapBigFishAnchor(
function mapBigFishSession(
session: BigFishSessionSnapshotResponse,
): CreationAgentSessionView {
// 中文注释:生成进度与资产完成记录不属于聊天历史,旧会话里的 action_result 也不再渲染为气泡。
const chatMessages = session.messages.filter(
(message) =>
message.kind === 'chat' ||
message.kind === 'summary' ||
message.kind === 'warning',
);
return {
sessionId: session.sessionId,
// 所有玩法的 Agent 聊天页顶部模块只保留操作与进度,不展示标题和引导副文案。
@@ -65,7 +73,7 @@ function mapBigFishSession(
session.anchorPack.growthLadder,
session.anchorPack.riskTempo,
].map(mapBigFishAnchor),
messages: session.messages,
messages: chatMessages,
recommendedReplies: [],
};
}

View File

@@ -102,3 +102,29 @@ test('puzzle workspace hides keyword fill before two turns', () => {
expect(screen.queryByRole('button', { name: '补充剩余设定' })).toBeNull();
});
test('puzzle workspace does not render progress action messages as chat bubbles', () => {
render(
<PuzzleAgentWorkspace
session={{
...baseSession,
messages: [
...baseSession.messages,
{
id: 'message-action-result-1',
role: 'assistant',
kind: 'action_result',
text: '拼图结果页草稿已生成。',
createdAt: '2026-04-24T10:01:00.000Z',
},
],
}}
onBack={() => {}}
onSubmitMessage={() => {}}
onExecuteAction={() => {}}
/>,
);
expect(screen.getByText('画面主体已经清楚,继续收束剩余关键词。')).toBeTruthy();
expect(screen.queryByText('拼图结果页草稿已生成。')).toBeNull();
});

View File

@@ -44,6 +44,14 @@ const PUZZLE_AGENT_THEME: CreationAgentTheme = {
function mapPuzzleSession(
session: PuzzleAgentSessionSnapshot,
): CreationAgentSessionView {
// 中文注释:生成进度与草稿写回记录不属于聊天历史,旧会话里的 action_result 也不再渲染为气泡。
const chatMessages = session.messages.filter(
(message) =>
message.kind === 'chat' ||
message.kind === 'summary' ||
message.kind === 'warning',
);
return {
sessionId: session.sessionId,
// 所有玩法的 Agent 聊天页顶部模块只保留操作与进度,不展示标题和引导副文案。
@@ -58,7 +66,7 @@ function mapPuzzleSession(
session.anchorPack.compositionHooks,
session.anchorPack.tagsAndForbidden,
],
messages: session.messages,
messages: chatMessages,
recommendedReplies: [],
};
}