diff --git a/docs/swarm/ui.md b/docs/swarm/ui.md index 3ee7479b..05fdf3e3 100644 --- a/docs/swarm/ui.md +++ b/docs/swarm/ui.md @@ -435,7 +435,10 @@ name that already holds an account; delete that account first to replace it. The agent's detail panel lists its linked accounts under **accounts**, one row per account: kind, name and host. Opening an agent makes one request, `GET /api/hives/{hive}/agents/{agent}/linked-accounts`, which returns every -account of that agent as names and hosts and never a credential. +account of that agent as names and hosts and never a credential. When the panel +fails to read the accounts, the inference settings or the resource caps, it +shows the reason as text. A list the panel already loaded stays on screen +beneath the error. | kind | one row per | name | host | | ------- | ------------------------------------------- | ----------- | ------------------------ | diff --git a/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx b/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx index f59c520e..5fb83a1c 100644 --- a/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx +++ b/frontend/packages/swarm-ui/src/agent/detail/AgentInference.tsx @@ -205,21 +205,23 @@ export function AgentInference({ agent }: { agent: string }) { }; }, [agent, reload]); - if (error) { - return ( - - ); + // Shown as text, not a hover title. Settings already loaded stay under a + // failed refetch, so a save that worked is not hidden by a read that did not. + const errorPanel = error ? ( + + ) : null; + if (view === null) { + return errorPanel ?? …; } - if (view === null) return …; const { configured, effective } = view; const swarmModels = configured?.subagent_models ?? []; return (
+ {errorPanel}
  • {effective ? ( diff --git a/frontend/packages/swarm-ui/src/agent/detail/AgentLimits.tsx b/frontend/packages/swarm-ui/src/agent/detail/AgentLimits.tsx index da7fb392..3860e3d9 100644 --- a/frontend/packages/swarm-ui/src/agent/detail/AgentLimits.tsx +++ b/frontend/packages/swarm-ui/src/agent/detail/AgentLimits.tsx @@ -114,19 +114,18 @@ export function AgentLimits({ agent }: { agent: string }) { }; }, [agent, reload]); - if (error) { - return ( - - ); + // Shown as text, not a hover title. Caps already loaded stay under a + // failed refetch, so a save that worked is not hidden by a read that did not. + const errorPanel = error ? ( + + ) : null; + if (caps === null) { + return errorPanel ?? …; } - if (caps === null) return …; return (
    + {errorPanel}
    • diff --git a/frontend/packages/swarm-ui/src/agent/detail/LinkedAccounts.tsx b/frontend/packages/swarm-ui/src/agent/detail/LinkedAccounts.tsx index daa3eed7..fa1eaf25 100644 --- a/frontend/packages/swarm-ui/src/agent/detail/LinkedAccounts.tsx +++ b/frontend/packages/swarm-ui/src/agent/detail/LinkedAccounts.tsx @@ -156,21 +156,26 @@ export function LinkedAccounts({ ); - if (error) { - return ( - - ); + // Shown as text, not a hover title. A list already loaded stays under a + // failed refetch, so a link or delete that worked is not hidden by a read + // that did not. + const errorPanel = error ? ( + + ) : null; + if (accounts === null) { + return errorPanel ?? …; } - if (accounts === null) return …; if (accounts.length === 0) { - return none linked; + return ( + <> + {errorPanel} + none linked + + ); } return ( <> + {errorPanel}
        {accounts.map((a) => (