Merge remote-tracking branch 'web/master' into feat/pixel_art2
This commit is contained in:
@@ -815,67 +815,69 @@ export function App({
|
||||
[gameChatOnly],
|
||||
);
|
||||
|
||||
function updateProjectSupervisorResponseStream(
|
||||
incoming: AgentRuntimeResponseStream | null | undefined,
|
||||
runtime: AgentRuntimeState,
|
||||
) {
|
||||
let nextStream = mergeProjectSupervisorResponseStream(
|
||||
projectSupervisorResponseStreamRef.current,
|
||||
incoming,
|
||||
runtime,
|
||||
);
|
||||
const candidateStream = nextStream;
|
||||
if (candidateStream?.status === 'ready' && gameChatOnly) {
|
||||
const text = candidateStream.accumulatedText.trim();
|
||||
const responseKey = projectSupervisorResponseStreamIdentity(
|
||||
candidateStream,
|
||||
const updateProjectSupervisorResponseStream = useCallback(
|
||||
(
|
||||
incoming: AgentRuntimeResponseStream | null | undefined,
|
||||
runtime: AgentRuntimeState,
|
||||
) => {
|
||||
let nextStream = mergeProjectSupervisorResponseStream(
|
||||
projectSupervisorResponseStreamRef.current,
|
||||
incoming,
|
||||
runtime,
|
||||
);
|
||||
const messageId = `runtime-response:${responseKey}`;
|
||||
const alreadyCommitted =
|
||||
gameChatCommittedResponseStreamKeysRef.current.has(responseKey) ||
|
||||
const candidateStream = nextStream;
|
||||
if (candidateStream?.status === 'ready' && gameChatOnly) {
|
||||
const text = candidateStream.accumulatedText.trim();
|
||||
const responseKey =
|
||||
projectSupervisorResponseStreamIdentity(candidateStream);
|
||||
const messageId = `runtime-response:${responseKey}`;
|
||||
const alreadyCommitted =
|
||||
gameChatCommittedResponseStreamKeysRef.current.has(responseKey) ||
|
||||
latestMessagesRef.current.some(
|
||||
(message) => message.messageId === messageId,
|
||||
);
|
||||
if (text && !alreadyCommitted) {
|
||||
gameChatCommittedResponseStreamKeysRef.current.add(responseKey);
|
||||
const nextMessage: ChatMessage = {
|
||||
role: 'assistant',
|
||||
text: candidateStream.accumulatedText,
|
||||
messageId,
|
||||
agentId: PROJECT_SUPERVISOR_AGENT_ID,
|
||||
updatedAt: candidateStream.updatedAt,
|
||||
runtimeOwned: true,
|
||||
};
|
||||
setMessages((current) => {
|
||||
if (current.some((message) => message.messageId === messageId)) {
|
||||
latestMessagesRef.current = current;
|
||||
return current;
|
||||
}
|
||||
const nextMessages = [...current, nextMessage];
|
||||
latestMessagesRef.current = nextMessages;
|
||||
return nextMessages;
|
||||
});
|
||||
}
|
||||
// Ready text is now a normal chat message; transientReply must not show
|
||||
// the same response a second time while polling/event delivery catches up.
|
||||
nextStream = null;
|
||||
} else if (
|
||||
candidateStream &&
|
||||
latestMessagesRef.current.some(
|
||||
(message) => message.messageId === messageId,
|
||||
);
|
||||
if (text && !alreadyCommitted) {
|
||||
gameChatCommittedResponseStreamKeysRef.current.add(responseKey);
|
||||
const nextMessage: ChatMessage = {
|
||||
role: 'assistant',
|
||||
text: candidateStream.accumulatedText,
|
||||
messageId,
|
||||
agentId: PROJECT_SUPERVISOR_AGENT_ID,
|
||||
updatedAt: candidateStream.updatedAt,
|
||||
runtimeOwned: true,
|
||||
};
|
||||
setMessages((current) => {
|
||||
if (current.some((message) => message.messageId === messageId)) {
|
||||
latestMessagesRef.current = current;
|
||||
return current;
|
||||
}
|
||||
const nextMessages = [...current, nextMessage];
|
||||
latestMessagesRef.current = nextMessages;
|
||||
return nextMessages;
|
||||
});
|
||||
(message) =>
|
||||
message.runtimeOwned &&
|
||||
message.role === 'assistant' &&
|
||||
message.text === candidateStream.accumulatedText &&
|
||||
typeof message.updatedAt === 'number' &&
|
||||
message.updatedAt >= candidateStream.startedAt,
|
||||
)
|
||||
) {
|
||||
// Keep the existing supervisor-chat behavior for restored history.
|
||||
nextStream = null;
|
||||
}
|
||||
// Ready text is now a normal chat message; transientReply must not show
|
||||
// the same response a second time while polling/event delivery catches up.
|
||||
nextStream = null;
|
||||
} else if (
|
||||
candidateStream &&
|
||||
latestMessagesRef.current.some(
|
||||
(message) =>
|
||||
message.runtimeOwned &&
|
||||
message.role === 'assistant' &&
|
||||
message.text === candidateStream.accumulatedText &&
|
||||
typeof message.updatedAt === 'number' &&
|
||||
message.updatedAt >= candidateStream.startedAt,
|
||||
)
|
||||
) {
|
||||
// Keep the existing supervisor-chat behavior for restored history.
|
||||
nextStream = null;
|
||||
}
|
||||
projectSupervisorResponseStreamRef.current = nextStream;
|
||||
setProjectSupervisorResponseStream(nextStream);
|
||||
}
|
||||
projectSupervisorResponseStreamRef.current = nextStream;
|
||||
setProjectSupervisorResponseStream(nextStream);
|
||||
},
|
||||
[gameChatOnly],
|
||||
);
|
||||
|
||||
function resetProjectSupervisorState() {
|
||||
projectSupervisorHistoryLoadVersionRef.current += 1;
|
||||
@@ -1155,7 +1157,7 @@ export function App({
|
||||
disposed = true;
|
||||
cleanup?.();
|
||||
};
|
||||
}, [updateProjectSupervisorRuntime]);
|
||||
}, [updateProjectSupervisorResponseStream, updateProjectSupervisorRuntime]);
|
||||
|
||||
useEffect(() => {
|
||||
const invoke = resolveTauriInvoke();
|
||||
|
||||
@@ -8,12 +8,12 @@ import type {
|
||||
} from '../src/app/types';
|
||||
import {
|
||||
formatAgentRuntimeEvent,
|
||||
mergeGameChatRuntimeResponseMessagesIntoHistory,
|
||||
projectRuntimeVisibleCurrentWork,
|
||||
projectRuntimeVisibleError,
|
||||
projectSupervisorChatRuntimeStatus,
|
||||
projectSupervisorResponseStreamIdentity,
|
||||
projectSupervisorVisibleConversationText,
|
||||
mergeGameChatRuntimeResponseMessagesIntoHistory,
|
||||
submitProjectSupervisorRuntimeTask,
|
||||
} from '../src/features/agent-runtime/model';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user