feat(models): capability toggles for custom models with upsert and live caps refresh

- AddCustomModelModal lets users pick vision/reasoning caps when adding a model
- POST /api/models/custom whitelists caps to booleans
- aliasRepo.addCustomModel upserts — re-adding updates caps/name in place
- /api/models includes custom llm models with stored caps overriding the heuristic
- useModelCaps refetches on customModelChanged instead of trusting a stale cache

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
decolua
2026-09-01 10:45:51 +07:00
co-authored by Claude Code
parent 90b52e06ff
commit 38f031f4c9
6 changed files with 97 additions and 23 deletions
+17 -8
View File
@@ -59,16 +59,25 @@ export function useModelCaps() {
const [byId, setById] = useState(() => cache?.byId || {});
useEffect(() => {
if (cache) {
setByFull(cache.byFull);
setById(cache.byId);
return;
}
let alive = true;
loadModelCaps().then((maps) => {
const sync = (maps) => {
if (alive) { setByFull(maps.byFull); setById(maps.byId); }
});
return () => { alive = false; };
};
if (cache) {
sync(cache);
} else {
loadModelCaps().then(sync);
}
// Custom models change at runtime — drop the shared cache and refetch
const invalidate = () => {
cache = null;
loadModelCaps().then(sync);
};
window.addEventListener("customModelChanged", invalidate);
return () => {
alive = false;
window.removeEventListener("customModelChanged", invalidate);
};
}, []);
const getCaps = useCallback(