mirror of
https://github.com/openswarm-ai/openswarm.git
synced 2026-08-17 18:25:42 +02:00
[Haik]: (moved logo out of island) (fixed notification derefrencing issues when u swap dashboards) (fixed chat header update issue where itd get stuck in the completed state)
This commit is contained in:
@@ -1285,6 +1285,13 @@ class AgentManager:
|
||||
})
|
||||
|
||||
session.sdk_session_id = None
|
||||
session.status = "running"
|
||||
await ws_manager.send_to_session(session_id, "agent:status", {
|
||||
"session_id": session_id,
|
||||
"status": "running",
|
||||
"session": session.model_dump(mode="json"),
|
||||
})
|
||||
|
||||
task = asyncio.create_task(self._run_agent_loop(
|
||||
session_id, new_content,
|
||||
images=target_msg.images,
|
||||
|
||||
@@ -3,6 +3,7 @@ import Box from '@mui/material/Box';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import SearchIcon from '@mui/icons-material/Search';
|
||||
import StopCircleOutlinedIcon from '@mui/icons-material/StopCircleOutlined';
|
||||
import CloseIcon from '@mui/icons-material/Close';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
@@ -217,7 +218,7 @@ const DynamicIsland: React.FC = () => {
|
||||
);
|
||||
|
||||
const trackedAgents: TrackedAgent[] = useMemo(() => {
|
||||
return trackedIds
|
||||
const agents = trackedIds
|
||||
.map((id): TrackedAgent | null => {
|
||||
const session = sessions[id];
|
||||
if (session && session.status !== 'draft') {
|
||||
@@ -230,7 +231,19 @@ const DynamicIsland: React.FC = () => {
|
||||
return null;
|
||||
})
|
||||
.filter((a): a is TrackedAgent => a !== null);
|
||||
}, [trackedIds, sessions, history]);
|
||||
|
||||
const trackedIdSet = new Set(trackedIds);
|
||||
for (const g of groups) {
|
||||
if (!trackedIdSet.has(g.sessionId)) {
|
||||
const session = sessions[g.sessionId];
|
||||
if (session && session.status !== 'draft') {
|
||||
agents.push({ id: g.sessionId, name: session.name, status: session.status, dashboardId: session.dashboard_id });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return agents;
|
||||
}, [trackedIds, sessions, history, groups]);
|
||||
|
||||
const activeAgents = useMemo(
|
||||
() => trackedAgents.filter((a) => a.status === 'running' || a.status === 'waiting_approval'),
|
||||
@@ -317,9 +330,9 @@ const DynamicIsland: React.FC = () => {
|
||||
// ---- Styling — uses the same neutral palette as the rest of the UI ----
|
||||
|
||||
const islandWidth = islandState === 'idle'
|
||||
? 126
|
||||
? 200
|
||||
: islandState === 'compact'
|
||||
? 220
|
||||
? 210
|
||||
: 400;
|
||||
|
||||
const islandBorderRadius = islandState === 'expanded' ? 14 : 50;
|
||||
@@ -413,7 +426,7 @@ const DynamicIsland: React.FC = () => {
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Idle pill
|
||||
// Idle pill — disabled search bar
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const IdlePill: React.FC<{ c: ReturnType<typeof useClaudeTokens> }> = ({ c }) => (
|
||||
@@ -423,40 +436,32 @@ const IdlePill: React.FC<{ c: ReturnType<typeof useClaudeTokens> }> = ({ c }) =>
|
||||
exit={{ opacity: 0, scale: 0.92 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<motion.div
|
||||
animate={{ scale: [1, 1.006, 1] }}
|
||||
transition={{ repeat: Infinity, duration: 4, ease: 'easeInOut' }}
|
||||
>
|
||||
<Tooltip title="Coming soon" arrow placement="bottom">
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: 0.6,
|
||||
px: 1.5,
|
||||
gap: 0.75,
|
||||
px: 1.25,
|
||||
height: 24,
|
||||
userSelect: 'none',
|
||||
cursor: 'default',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="img"
|
||||
src="./logo.png"
|
||||
alt="OpenSwarm"
|
||||
sx={{ width: 13, height: 13, borderRadius: 0.5, opacity: 0.6 }}
|
||||
/>
|
||||
<SearchIcon sx={{ fontSize: 13, color: c.text.ghost, flexShrink: 0 }} />
|
||||
<Typography
|
||||
sx={{
|
||||
color: c.text.tertiary,
|
||||
fontSize: '0.68rem',
|
||||
fontWeight: 500,
|
||||
letterSpacing: 0.3,
|
||||
color: c.text.ghost,
|
||||
fontSize: '0.66rem',
|
||||
fontWeight: 400,
|
||||
lineHeight: 1,
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
OpenSwarm
|
||||
Search...
|
||||
</Typography>
|
||||
</Box>
|
||||
</motion.div>
|
||||
</Tooltip>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
@@ -512,12 +517,6 @@ const CompactPill: React.FC<{
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<Box
|
||||
component="img"
|
||||
src="./logo.png"
|
||||
alt=""
|
||||
sx={{ width: 11, height: 11, borderRadius: 0.25, opacity: 0.45, flexShrink: 0 }}
|
||||
/>
|
||||
</Box>
|
||||
</motion.div>
|
||||
);
|
||||
|
||||
@@ -351,6 +351,36 @@ const AppShell: React.FC = () => {
|
||||
</Tooltip>
|
||||
|
||||
<DynamicIsland />
|
||||
|
||||
<Box sx={{ flex: 1 }} />
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
gap: 0.75,
|
||||
pr: 1.5,
|
||||
WebkitAppRegion: 'no-drag',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="img"
|
||||
src="./logo.png"
|
||||
alt="OpenSwarm"
|
||||
sx={{ width: 16, height: 16, borderRadius: 0.5, opacity: 0.6 }}
|
||||
/>
|
||||
<Typography
|
||||
sx={{
|
||||
color: c.text.tertiary,
|
||||
fontSize: '0.72rem',
|
||||
fontWeight: 500,
|
||||
letterSpacing: 0.3,
|
||||
lineHeight: 1,
|
||||
}}
|
||||
>
|
||||
OpenSwarm
|
||||
</Typography>
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
{showUpdateBanner && (
|
||||
|
||||
@@ -520,7 +520,13 @@ const agentsSlice = createSlice({
|
||||
},
|
||||
|
||||
updateSession(state, action: PayloadAction<AgentSession>) {
|
||||
if (state.history[action.payload.id]) return;
|
||||
if (state.history[action.payload.id]) {
|
||||
if (action.payload.status === 'running') {
|
||||
delete state.history[action.payload.id];
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
const existing = state.sessions[action.payload.id];
|
||||
state.sessions[action.payload.id] = {
|
||||
...action.payload,
|
||||
@@ -720,8 +726,9 @@ const agentsSlice = createSlice({
|
||||
.addCase(fetchSessions.fulfilled, (state, action) => {
|
||||
state.loading = false;
|
||||
const sessions: Record<string, AgentSession> = {};
|
||||
const trackedSet = new Set(state.trackedNotificationIds);
|
||||
for (const [id, existing] of Object.entries(state.sessions)) {
|
||||
if (existing.status === 'draft') sessions[id] = existing;
|
||||
if (existing.status === 'draft' || trackedSet.has(id)) sessions[id] = existing;
|
||||
}
|
||||
for (const s of action.payload) {
|
||||
const existing = state.sessions[s.id];
|
||||
@@ -732,6 +739,11 @@ const agentsSlice = createSlice({
|
||||
};
|
||||
}
|
||||
state.sessions = sessions;
|
||||
for (const s of action.payload) {
|
||||
if ((s.status === 'running' || s.status === 'waiting_approval') && !state.trackedNotificationIds.includes(s.id)) {
|
||||
state.trackedNotificationIds.push(s.id);
|
||||
}
|
||||
}
|
||||
})
|
||||
.addCase(fetchSessions.rejected, (state) => {
|
||||
state.loading = false;
|
||||
@@ -783,6 +795,18 @@ const agentsSlice = createSlice({
|
||||
session.system_prompt = action.payload.systemPrompt;
|
||||
}
|
||||
})
|
||||
.addCase(sendMessage.pending, (state, action) => {
|
||||
const session = state.sessions[action.meta.arg.sessionId];
|
||||
if (session) {
|
||||
session.status = 'running';
|
||||
}
|
||||
})
|
||||
.addCase(editMessage.pending, (state, action) => {
|
||||
const session = state.sessions[action.meta.arg.sessionId];
|
||||
if (session) {
|
||||
session.status = 'running';
|
||||
}
|
||||
})
|
||||
.addCase(stopAgent.fulfilled, (state, action) => {
|
||||
const session = state.sessions[action.payload];
|
||||
if (session) {
|
||||
@@ -829,6 +853,7 @@ const agentsSlice = createSlice({
|
||||
state.activeSessionId = null;
|
||||
}
|
||||
state.expandedSessionIds = state.expandedSessionIds.filter((id) => id !== sessionId);
|
||||
state.trackedNotificationIds = state.trackedNotificationIds.filter((id) => id !== sessionId);
|
||||
})
|
||||
.addCase(closeSession.rejected, (state, action) => {
|
||||
const sessionId = action.meta.arg.sessionId;
|
||||
@@ -851,6 +876,7 @@ const agentsSlice = createSlice({
|
||||
state.activeSessionId = null;
|
||||
}
|
||||
state.expandedSessionIds = state.expandedSessionIds.filter((id) => id !== sessionId);
|
||||
state.trackedNotificationIds = state.trackedNotificationIds.filter((id) => id !== sessionId);
|
||||
})
|
||||
.addCase(deleteSession.fulfilled, (state, action) => {
|
||||
const sessionId = action.payload;
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user