mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-09-11 12:17:45 +02:00
[aidan] fix/browser-early-close: let agent keep browser open when result lives on the page (#88)
This commit is contained in:
@@ -59,6 +59,7 @@ export interface BrowserCardPosition {
|
||||
zOrder: number;
|
||||
/** Agent session that spawned this browser; auto-removed when its owner reaches terminal state. */
|
||||
spawned_by?: string | null;
|
||||
keep_open?: boolean;
|
||||
/** Dashboard this card belongs to; cards render and persist only on their owning dashboard. */
|
||||
dashboard_id?: string;
|
||||
}
|
||||
@@ -663,6 +664,14 @@ const dashboardLayoutSlice = createSlice({
|
||||
delete state.endingBrowserCards[action.payload];
|
||||
},
|
||||
|
||||
keepBrowserCardOpen(state, action: PayloadAction<string>) {
|
||||
const card = state.browserCards[action.payload];
|
||||
if (!card) return;
|
||||
card.keep_open = true;
|
||||
// Undo any in-flight ending mark in case a close path raced ahead.
|
||||
delete state.endingBrowserCards[action.payload];
|
||||
},
|
||||
|
||||
suspendBrowserCard(state, action: PayloadAction<{ browserId: string; dataUrl: string }>) {
|
||||
if (!state.browserCards[action.payload.browserId]) return;
|
||||
state.suspendedBrowserCards[action.payload.browserId] = {
|
||||
@@ -1098,6 +1107,7 @@ export const {
|
||||
resumeBrowserCard,
|
||||
markBrowserCardEnding,
|
||||
cancelBrowserCardEnding,
|
||||
keepBrowserCardOpen,
|
||||
pasteBrowserCard,
|
||||
updateBrowserCardUrl,
|
||||
addBrowserTab,
|
||||
|
||||
@@ -23,7 +23,7 @@ import {
|
||||
clearTurnLabel,
|
||||
} from '../state/agentsSlice';
|
||||
import { streamStart, streamDelta, streamEnd, clearStreamingForSession } from '../state/streamingSlice';
|
||||
import { addBrowserCardFromBackend, markBrowserCardEnding, setBrowserCardPosition, setGlowingBrowserCards, GRID_GAP } from '../state/dashboardLayoutSlice';
|
||||
import { addBrowserCardFromBackend, markBrowserCardEnding, keepBrowserCardOpen, setBrowserCardPosition, setGlowingBrowserCards, GRID_GAP } from '../state/dashboardLayoutSlice';
|
||||
import { upsertOutput } from '../state/outputsSlice';
|
||||
import { displaySessionName } from '../state/sessionDisplay';
|
||||
import { getAuthToken } from '../config';
|
||||
@@ -510,7 +510,7 @@ class WebSocketManager {
|
||||
) {
|
||||
const browserCards = store.getState().dashboardLayout.browserCards;
|
||||
for (const card of Object.values(browserCards)) {
|
||||
if (card.spawned_by === session_id) {
|
||||
if (card.spawned_by === session_id && !card.keep_open) {
|
||||
store.dispatch(markBrowserCardEnding({
|
||||
browserId: card.browser_id, status: data.status,
|
||||
}));
|
||||
@@ -733,7 +733,7 @@ class WebSocketManager {
|
||||
if (closedStatus === 'completed' || closedStatus === 'error') {
|
||||
const browserCards = store.getState().dashboardLayout.browserCards;
|
||||
for (const card of Object.values(browserCards)) {
|
||||
if (card.spawned_by === session_id) {
|
||||
if (card.spawned_by === session_id && !card.keep_open) {
|
||||
store.dispatch(markBrowserCardEnding({
|
||||
browserId: card.browser_id, status: closedStatus,
|
||||
}));
|
||||
@@ -743,6 +743,12 @@ class WebSocketManager {
|
||||
}
|
||||
break;
|
||||
|
||||
case 'dashboard:browser_card_keep':
|
||||
if (data.browser_id) {
|
||||
store.dispatch(keepBrowserCardOpen(data.browser_id));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'dashboard:browser_card_added':
|
||||
if (data.browser_card) {
|
||||
// Tag with origin dashboard so the card renders only on the dashboard
|
||||
|
||||
Reference in New Issue
Block a user