Skip to content
This repository was archived by the owner on Apr 14, 2026. It is now read-only.

Commit 0268f93

Browse files
committed
restore floating restart card, treat local providers as available
Bring back the floating restart notification card below the settings modal (message only, no restart button). The card fades in on credential changes and auto-dismisses when leaving the providers section. Treat setupMethod: "local" providers (e.g. Ollama) as always available when computing hasModelProvider, matching the Goose backend's check_provider_configured behavior. This prevents local-only users from seeing a perpetual needs_model indicator on the Goose agent card.
1 parent 7f31faf commit 0268f93

File tree

5 files changed

+288
-218
lines changed

5 files changed

+288
-218
lines changed

src/features/providers/hooks/useCredentials.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ interface UseCredentialsReturn {
1212
configuredIds: Set<string>;
1313
loading: boolean;
1414
saving: boolean;
15+
needsRestart: boolean;
1516
getConfig: (providerId: string) => Promise<ProviderFieldValue[]>;
1617
save: (key: string, value: string) => Promise<void>;
1718
remove: (providerId: string) => Promise<void>;
@@ -22,6 +23,7 @@ export function useCredentials(): UseCredentialsReturn {
2223
const [statuses, setStatuses] = useState<ProviderStatus[]>([]);
2324
const [loading, setLoading] = useState(true);
2425
const [saving, setSaving] = useState(false);
26+
const [needsRestart, setNeedsRestart] = useState(false);
2527

2628
const refreshStatuses = useCallback(async () => {
2729
const nextStatuses = await checkAllProviderStatus();
@@ -51,6 +53,7 @@ export function useCredentials(): UseCredentialsReturn {
5153
try {
5254
await saveProviderField(key, value);
5355
await refreshStatuses();
56+
setNeedsRestart(true);
5457
} finally {
5558
setSaving(false);
5659
}
@@ -64,6 +67,7 @@ export function useCredentials(): UseCredentialsReturn {
6467
try {
6568
await deleteProviderConfig(providerId);
6669
await refreshStatuses();
70+
setNeedsRestart(true);
6771
} finally {
6872
setSaving(false);
6973
}
@@ -73,12 +77,14 @@ export function useCredentials(): UseCredentialsReturn {
7377

7478
const completeNativeSetup = useCallback(async () => {
7579
await refreshStatuses();
80+
setNeedsRestart(true);
7681
}, [refreshStatuses]);
7782

7883
return {
7984
configuredIds,
8085
loading,
8186
saving,
87+
needsRestart,
8288
getConfig,
8389
save,
8490
remove,

src/features/settings/ui/ProvidersSettings.tsx

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,12 @@ function toDisplayInfo(
4242

4343
interface ProvidersSettingsProps {
4444
scrollContainerRef?: React.RefObject<HTMLElement | null>;
45+
onNeedsRestart?: () => void;
4546
}
4647

4748
export function ProvidersSettings({
4849
scrollContainerRef,
50+
onNeedsRestart,
4951
}: ProvidersSettingsProps) {
5052
const { t } = useTranslation(["settings", "common"]);
5153
const [showAllModels, setShowAllModels] = useState(false);
@@ -66,20 +68,32 @@ export function ProvidersSettings({
6668
configuredIds,
6769
loading,
6870
saving,
71+
needsRestart,
6972
getConfig,
7073
save,
7174
remove,
7275
completeNativeSetup,
7376
} = useCredentials();
7477

78+
useEffect(() => {
79+
if (needsRestart) onNeedsRestart?.();
80+
}, [needsRestart, onNeedsRestart]);
81+
7582
const modelProviderIds = useMemo(
7683
() => new Set(getModelProviders().map((m) => m.id)),
7784
[],
7885
);
7986

87+
const hasLocalProvider = useMemo(
88+
() => getModelProviders().some((m) => m.setupMethod === "local"),
89+
[],
90+
);
91+
8092
const hasModelProvider = useMemo(
81-
() => [...configuredIds].some((id) => modelProviderIds.has(id)),
82-
[configuredIds, modelProviderIds],
93+
() =>
94+
hasLocalProvider ||
95+
[...configuredIds].some((id) => modelProviderIds.has(id)),
96+
[configuredIds, hasLocalProvider, modelProviderIds],
8397
);
8498

8599
const scrollToModels = useCallback(() => {

0 commit comments

Comments
 (0)