修复策划 Agent 事件监听时序
让策划 Agent 回合在调用 Runtime 前等待 design-agent-update 监听注册完成 覆盖普通消息、澄清、重试和阶段批准入口 保持 GameAgent、Direct/Codex 与退役入口行为不变
This commit is contained in:
@@ -596,6 +596,12 @@ export function App({
|
||||
projectPath: string;
|
||||
clientTurnId: string;
|
||||
} | null>(null);
|
||||
const designAgentEventSubscriptionReadyRef = useRef<Promise<void> | null>(
|
||||
null,
|
||||
);
|
||||
const designAgentEventSubscriptionResolveRef = useRef<(() => void) | null>(
|
||||
null,
|
||||
);
|
||||
// 做方案入口独立成链:立项策划需要委派、澄清 pending 与 GDD 审批,这些只存在于
|
||||
// Supervisor Runtime;direct-codex 是单回合「生成→试玩→修」循环,没有对应机制。
|
||||
// 因此策划入口不走产品默认的 direct-codex,做游戏与做素材保持 master 的新默认。
|
||||
@@ -849,6 +855,22 @@ export function App({
|
||||
}
|
||||
}
|
||||
|
||||
function designAgentEventSubscriptionReady() {
|
||||
if (!designAgentEventSubscriptionReadyRef.current) {
|
||||
designAgentEventSubscriptionReadyRef.current = new Promise<void>(
|
||||
(resolve) => {
|
||||
designAgentEventSubscriptionResolveRef.current = resolve;
|
||||
},
|
||||
);
|
||||
}
|
||||
return designAgentEventSubscriptionReadyRef.current;
|
||||
}
|
||||
|
||||
function resolveDesignAgentEventSubscriptionReady() {
|
||||
designAgentEventSubscriptionResolveRef.current?.();
|
||||
designAgentEventSubscriptionResolveRef.current = null;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const timer = window.setInterval(() => {
|
||||
const target = planningV2TransientReplyTargetRef.current;
|
||||
@@ -1038,6 +1060,7 @@ export function App({
|
||||
projectPath: nextProjectPath,
|
||||
clientTurnId,
|
||||
};
|
||||
await designAgentEventSubscriptionReady();
|
||||
setChatAgentBusy(true);
|
||||
setProjectSupervisorRuntimeError('');
|
||||
setPlanningV2TransientReplyTarget('');
|
||||
@@ -1992,8 +2015,14 @@ export function App({
|
||||
}, [planningV2Active]);
|
||||
|
||||
useEffect(() => {
|
||||
const ready = designAgentEventSubscriptionReady();
|
||||
if (!canSubscribeTauriEvents() || !planningV2Active) {
|
||||
return;
|
||||
resolveDesignAgentEventSubscriptionReady();
|
||||
return () => {
|
||||
if (designAgentEventSubscriptionReadyRef.current === ready) {
|
||||
designAgentEventSubscriptionReadyRef.current = null;
|
||||
}
|
||||
};
|
||||
}
|
||||
let cleanup: (() => void) | null = null;
|
||||
let disposed = false;
|
||||
@@ -2020,16 +2049,23 @@ export function App({
|
||||
}
|
||||
})
|
||||
.then((unlisten) => {
|
||||
resolveDesignAgentEventSubscriptionReady();
|
||||
if (disposed) {
|
||||
unlisten();
|
||||
return;
|
||||
}
|
||||
cleanup = unlisten;
|
||||
})
|
||||
.catch(() => undefined);
|
||||
.catch(() => {
|
||||
resolveDesignAgentEventSubscriptionReady();
|
||||
});
|
||||
return () => {
|
||||
disposed = true;
|
||||
cleanup?.();
|
||||
resolveDesignAgentEventSubscriptionReady();
|
||||
if (designAgentEventSubscriptionReadyRef.current === ready) {
|
||||
designAgentEventSubscriptionReadyRef.current = null;
|
||||
}
|
||||
};
|
||||
// applyDesignView 读的是 refs 和当前项目路径,
|
||||
// 把它写进依赖会在每轮回复时重订事件。
|
||||
@@ -11831,12 +11867,15 @@ export function App({
|
||||
setPlanningV2Reasoning('');
|
||||
setChatAgentBusy(true);
|
||||
setPlanGddDecisionBusy(true);
|
||||
void invoke<DesignView>('decide_design_phase', {
|
||||
projectPath: nextProjectPath,
|
||||
clientTurnId,
|
||||
requestId,
|
||||
approved,
|
||||
})
|
||||
void designAgentEventSubscriptionReady()
|
||||
.then(() =>
|
||||
invoke<DesignView>('decide_design_phase', {
|
||||
projectPath: nextProjectPath,
|
||||
clientTurnId,
|
||||
requestId,
|
||||
approved,
|
||||
}),
|
||||
)
|
||||
.then((view) => {
|
||||
if (
|
||||
localProjectPathRef.current !== nextProjectPath ||
|
||||
|
||||
Reference in New Issue
Block a user