diff --git a/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx b/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx
index 8c6312681..4a21a7550 100644
--- a/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx
+++ b/apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx
@@ -1,8 +1,8 @@
import {
ArrowUp,
AtSign,
- Brain,
ChevronDown,
+ Lightbulb,
Loader2,
Settings,
Wrench,
@@ -125,6 +125,7 @@ function AgentReasoning({
label?: string;
testId?: string;
}) {
+ const [expanded, setExpanded] = useState(false);
// 折叠态:单行纯文本预览(走 Markdown AST 取文字,链接只留字面文字、不含目标)。
const preview = agentProcessPreview(text);
return (
@@ -134,11 +135,14 @@ function AgentReasoning({
className="design-agent-reasoning"
aria-label={label}
data-testid={testId}
+ onToggle={(event) =>
+ setExpanded((event.currentTarget as HTMLDetailsElement).open)
+ }
>
}
- preview={preview || '思考过程'}
+ icon={}
+ preview={expanded ? '思考过程' : preview || '思考过程'}
chevron={}
/>
@@ -319,6 +323,16 @@ export function ProjectSupervisorView({
: [];
const activeTurnStartedAt =
directTurns.find((turn) => turn.active)?.startedAt ?? 0;
+ const latestDirectTurn = directTurns.at(-1);
+ // 仅是首个响应到达前的临时提示,不创建聊天条目或第二套回合状态。
+ const awaitingFirstResponse =
+ directCodex &&
+ (runBusy || directTurnRunning) &&
+ !turnCancelling &&
+ !runtimePanelProps.error &&
+ Boolean(latestDirectTurn?.users.length) &&
+ latestDirectTurn?.process.length === 0 &&
+ latestDirectTurn?.finals.length === 0;
// 初始占位气泡只是"最初那条消息还没有正式条目"时的顶位,两种情况下不再渲染:
// - 已经翻出更早的历史(`hasEarlierConversationMessages`):这里不是对话开头,不补占位;
// - Direct 模式已经有了正式用户条目:正式气泡自己会显示,占位再渲染就是同一条消息出现两次。
@@ -648,6 +662,18 @@ export function ProjectSupervisorView({
) : null}
+ {awaitingFirstResponse ? (
+
+
+ 思考中…
+
+ ) : null}
{directCodex ? null : planningSurfaceActive ? (
call.status === 'failed')
- ? 'failed'
- : 'completed';
+ const hasFailure = orderedCalls.some((call) => call.status === 'failed');
+ const status = toolRunning ? 'running' : hasFailure ? 'failed' : 'completed';
// 用户口径:`执行了 X 个操作,耗时 XXX`。耗时属于**这一组**(不是整轮),可见文本里用
// 中文逗号连起来,所以分隔符跟着 meta 一起进 DOM。
// 顺序按用户口径:`执行了 X 个操作,耗时 XXX`,运行状态挂到最后,不插在中间。
const headMeta = [
timing.durationText ? `耗时 ${timing.durationText}` : '',
+ hasFailure ? '有操作失败' : '',
toolRunning ? '进行中' : '',
]
.filter(Boolean)
@@ -101,6 +99,7 @@ export function ToolCallGroup({
data-testid="agent-tool-call-group"
aria-label="陶泥儿执行过程"
data-status={status}
+ data-has-failure={hasFailure ? 'true' : undefined}
data-duration-ms={timing.durationMs ?? ''}
>