Merge branch 'main' into browser-use

This commit is contained in:
Simos Mikelatos
2026-06-16 19:02:36 +02:00
committed by GitHub
17 changed files with 1458 additions and 34 deletions

View File

@@ -121,16 +121,12 @@ function AppContentInner() {
}, [refreshRunningSessions]);
useEffect(() => {
if (processingSessions.size === 0) {
return;
}
const interval = window.setInterval(() => {
void refreshRunningSessions();
}, 5000);
return () => window.clearInterval(interval);
}, [processingSessions.size, refreshRunningSessions]);
}, [refreshRunningSessions]);
usePaletteOpsRegister({
openSettings,

View File

@@ -202,7 +202,9 @@ export function useChatRealtimeHandlers({
// indicator derives from the processing map, so deleting the entry
// hides it immediately and atomically.
onSessionIdle?.(sid);
setPendingPermissionRequests([]);
if (sid === activeViewSessionId) {
setPendingPermissionRequests([]);
}
if (msg.aborted) {
// Abort was requested — the complete event confirms it. No
@@ -232,17 +234,19 @@ export function useChatRealtimeHandlers({
case 'permission_request': {
if (!msg.requestId) break;
setPendingPermissionRequests((prev) => {
if (prev.some((r: PendingPermissionRequest) => r.requestId === msg.requestId)) return prev;
return [...prev, {
requestId: msg.requestId as string,
toolName: (msg.toolName as string) || 'UnknownTool',
input: msg.input,
context: msg.context,
sessionId: sid || null,
receivedAt: new Date(),
}];
});
if (sid === activeViewSessionId) {
setPendingPermissionRequests((prev) => {
if (prev.some((r: PendingPermissionRequest) => r.requestId === msg.requestId)) return prev;
return [...prev, {
requestId: msg.requestId as string,
toolName: (msg.toolName as string) || 'UnknownTool',
input: msg.input,
context: msg.context,
sessionId: sid || null,
receivedAt: new Date(),
}];
});
}
if (sid) {
onSessionProcessing?.(sid);
}
@@ -250,7 +254,7 @@ export function useChatRealtimeHandlers({
}
case 'permission_cancelled': {
if (msg.requestId) {
if (msg.requestId && sid === activeViewSessionId) {
setPendingPermissionRequests((prev) => prev.filter((r: PendingPermissionRequest) => r.requestId !== msg.requestId));
}
break;

View File

@@ -452,14 +452,31 @@ export function useChatSessionState({
return;
}
const sessionKey = `${selectedSession.id}:${selectedProject.projectId}`;
const selectedSessionId = selectedSession.id;
const sessionKey = `${selectedSessionId}:${selectedProject.projectId}`;
const subscribeToSelectedSession = () => {
if (!ws) {
return;
}
statusCheckSentAtRef.current.set(selectedSessionId, Date.now());
sendMessage({
type: 'chat.subscribe',
sessions: [{
sessionId: selectedSessionId,
lastSeq: lastSeqRef.current.get(selectedSessionId) ?? 0,
}],
});
};
// Skip if already loaded and fresh
if (lastLoadedSessionKeyRef.current === sessionKey && sessionStore.has(selectedSession.id) && !sessionStore.isStale(selectedSession.id)) {
if (lastLoadedSessionKeyRef.current === sessionKey && sessionStore.has(selectedSessionId) && !sessionStore.isStale(selectedSessionId)) {
subscribeToSelectedSession();
return;
}
const sessionChanged = currentSessionId !== null && currentSessionId !== selectedSession.id;
const sessionChanged = currentSessionId !== null && currentSessionId !== selectedSessionId;
if (sessionChanged) {
resetStreamingState();
}
@@ -482,29 +499,20 @@ export function useChatSessionState({
setTokenBudget(null);
}
setCurrentSessionId(selectedSession.id);
setCurrentSessionId(selectedSessionId);
// Subscribe to the session's live run (if any): the ack reconciles the
// processing indicator, re-attaches a mid-flight stream to this socket,
// and replays any live events missed since `lastSeq`. Recording the send
// time lets the ack handler discard idle acks that a newer request has
// since outdated.
if (ws) {
statusCheckSentAtRef.current.set(selectedSession.id, Date.now());
sendMessage({
type: 'chat.subscribe',
sessions: [{
sessionId: selectedSession.id,
lastSeq: lastSeqRef.current.get(selectedSession.id) ?? 0,
}],
});
}
subscribeToSelectedSession();
lastLoadedSessionKeyRef.current = sessionKey;
// Fetch from server → store updates → chatMessages re-derives automatically
setIsLoadingSessionMessages(true);
sessionStore.fetchFromServer(selectedSession.id, {
sessionStore.fetchFromServer(selectedSessionId, {
limit: MESSAGES_PER_PAGE,
offset: 0,
}).then(slot => {