diff --git a/apps/ai-game-creator-shell/src/App.tsx b/apps/ai-game-creator-shell/src/App.tsx index 78cb692fb..820528d4c 100644 --- a/apps/ai-game-creator-shell/src/App.tsx +++ b/apps/ai-game-creator-shell/src/App.tsx @@ -489,6 +489,26 @@ function directCodexConversationMessageId( } /** 从 `direct-codex::assistant` 反解回合 id;不是这个形状就返回 `null`。 */ +/** + * 从任意 direct-codex 消息 id 解出回合 id:`direct-codex::user` / `:assistant` 都认。 + * + * 历史里 assistant 消息存的是 Codex 原始 id(没有前缀),解不出来就返回 null—— + * 调用方必须容忍"全部解不出来"的情况,不能因此把数据整批过滤掉。 + */ +function directCodexTurnIdFromConversationMessageId(messageId: string) { + if (!messageId.startsWith(DIRECT_CODEX_CONVERSATION_MESSAGE_ID_PREFIX)) { + return null; + } + const rest = messageId.slice(DIRECT_CODEX_CONVERSATION_MESSAGE_ID_PREFIX.length); + for (const suffix of [':user', ':assistant']) { + if (rest.endsWith(suffix)) { + const turnId = rest.slice(0, -suffix.length).trim(); + return turnId || null; + } + } + return rest.trim() || null; +} + function directCodexTurnIdFromAssistantMessageId(messageId: string) { const suffix = ':assistant'; if ( @@ -12250,11 +12270,15 @@ export function App({ messages .map((message) => message.messageId) .filter((messageId): messageId is string => Boolean(messageId)) - .map(directCodexTurnIdFromAssistantMessageId) + .map(directCodexTurnIdFromConversationMessageId) .filter((turnId): turnId is string => Boolean(turnId)), ); + // 老历史里 assistant 消息是 Codex 原始 id,一个回合都解不出来:此时**不过滤**, + // 否则工具卡片与回合流会被整批丢掉(实机表现:重进会话后工具与流全部消失)。 + const keepAllDirectCodexTurns = visibleTurnIds.size === 0; const visibleToolCalls = directToolCalls.filter( (call) => + keepAllDirectCodexTurns || visibleTurnIds.has(call.turnId) || call.turnId === activeDirectCodexTurnRef.current?.turnId, ); @@ -12262,6 +12286,7 @@ export function App({ // 没有流条目的回合由视图自己回退到原来的渲染。 const visibleTurnStreamItems = directTurnStream.filter( (item) => + keepAllDirectCodexTurns || visibleTurnIds.has(item.turnId) || item.turnId === activeDirectCodexTurnRef.current?.turnId, );