feat: server-side override pause/resume for builtin adapter types

Replace the client-side-only override store with a real server-side
toggle. When a developer pauses the external override, the server swaps
ALL adapter behavior back to the builtin — execute handler, model listing,
config schema, detection — not just the UI parser.

Server changes:
- registry.ts: builtinFallbacks map + pausedOverrides set + setOverridePaused()
- routes/adapters.ts: PATCH /api/adapters/:type/override endpoint + overridePaused in list

UI changes:
- adapters.ts: setOverridePaused API method + overridePaused on AdapterInfo
- AdapterManager: overrideMutation calls server, instant feedback via invalidate()
- use-disabled-adapters.ts: reads adapter.overridePaused from server response

Removed:
- disabled-overrides-store.ts: no longer needed (server is the source of truth)

Note: already-running agent sessions keep the adapter they started with.
Only new sessions use the swapped adapter.
This commit is contained in:
HenkDz 2026-04-04 13:17:21 +01:00
parent 4efe018a8f
commit b81d765d2e
6 changed files with 127 additions and 126 deletions

View file

@ -1,8 +1,7 @@
import { useEffect, useMemo, useSyncExternalStore } from "react";
import { useEffect, useMemo } from "react";
import { useQuery } from "@tanstack/react-query";
import { adaptersApi } from "@/api/adapters";
import { setDisabledAdapterTypes } from "@/adapters/disabled-store";
import { isOverrideDisabled, subscribeToOverrides, getOverridesSnapshot } from "@/adapters/disabled-overrides-store";
import { syncExternalAdapters } from "@/adapters/registry";
import { queryKeys } from "@/lib/queryKeys";
@ -24,10 +23,6 @@ export function useDisabledAdaptersSync(): Set<string> {
staleTime: 5 * 60 * 1000,
});
// Subscribe to the client-side override store so that
// syncExternalAdapters() re-runs when overrides are toggled.
useSyncExternalStore(subscribeToOverrides, getOverridesSnapshot);
// Eagerly register external adapter types in the UI registry so that
// consumers calling listUIAdapters() in the same render cycle see them.
// This is idempotent — already-registered types are skipped.
@ -39,7 +34,7 @@ export function useDisabledAdaptersSync(): Set<string> {
type: a.type,
label: a.label,
disabled: a.disabled,
overrideDisabled: a.overriddenBuiltin ? isOverrideDisabled(a.type) : undefined,
overrideDisabled: a.overridePaused,
})),
);
}