feat: implement model lock functionality for connection management

This commit is contained in:
decolua committed 2026-02-27 10:29:11 +07:00
1 parent 1f4423d444
commit 25c2ad7360
6 files changed
+219 -205

No files matched your search

@@ -919,20 +919,29 @@ function ConnectionRow({ connection, isOAuth, isFirst, isLast, onMoveUp, onMoveD
// Use useState + useEffect for impure Date.now() to avoid calling during render
const [isCooldown, setIsCooldown] = useState(false);
// Get earliest model lock timestamp (useEffect handles the Date.now() comparison)
const modelLockUntil = Object.entries(connection)
.filter(([k]) => k.startsWith("modelLock_"))
.map(([, v]) => v)
.filter(v => !!v)
.sort()[0] || null;
useEffect(() => {
const checkCooldown = () => {
const cooldown = connection.rateLimitedUntil &&
new Date(connection.rateLimitedUntil).getTime() > Date.now();
setIsCooldown(cooldown);
const until = Object.entries(connection)
.filter(([k]) => k.startsWith("modelLock_"))
.map(([, v]) => v)
.filter(v => v && new Date(v).getTime() > Date.now())
.sort()[0] || null;
setIsCooldown(!!until);
};
checkCooldown();
// Update every second while in cooldown
const interval = connection.rateLimitedUntil ? setInterval(checkCooldown, 1000) : null;
const interval = modelLockUntil ? setInterval(checkCooldown, 1000) : null;
return () => {
if (interval) clearInterval(interval);
};
}, [connection.rateLimitedUntil]);
}, [modelLockUntil]);
// Determine effective status (override unavailable if cooldown expired)
const effectiveStatus = (connection.testStatus === "unavailable" && !isCooldown)
@@ -975,7 +984,7 @@ function ConnectionRow({ connection, isOAuth, isFirst, isLast, onMoveUp, onMoveD
<Badge variant={getStatusVariant()} size="sm" dot>
{connection.isActive === false ? "disabled" : (effectiveStatus || "Unknown")}
</Badge>
{isCooldown && connection.isActive !== false && <CooldownTimer until={connection.rateLimitedUntil} />}
{isCooldown && connection.isActive !== false && <CooldownTimer until={modelLockUntil} />}
{connection.lastError && connection.isActive !== false && (
<span className="text-xs text-red-500 truncate max-w-[300px]" title={connection.lastError}>
{connection.lastError}
@@ -1014,7 +1023,7 @@ ConnectionRow.propTypes = {
name: PropTypes.string,
email: PropTypes.string,
displayName: PropTypes.string,
rateLimitedUntil: PropTypes.string,
modelLockUntil: PropTypes.string,
testStatus: PropTypes.string,
isActive: PropTypes.bool,
lastError: PropTypes.string,
@@ -1144,20 +1144,28 @@ function ConnectionRow({ connection, isOAuth, isFirst, isLast, onMoveUp, onMoveD
// Use useState + useEffect for impure Date.now() to avoid calling during render
const [isCooldown, setIsCooldown] = useState(false);
const modelLockUntil = Object.entries(connection)
.filter(([k]) => k.startsWith("modelLock_"))
.map(([, v]) => v)
.filter(v => v && new Date(v).getTime() > Date.now())
.sort()[0] || null;
useEffect(() => {
const checkCooldown = () => {
const cooldown = connection.rateLimitedUntil &&
new Date(connection.rateLimitedUntil).getTime() > Date.now();
setIsCooldown(cooldown);
const until = Object.entries(connection)
.filter(([k]) => k.startsWith("modelLock_"))
.map(([, v]) => v)
.filter(v => v && new Date(v).getTime() > Date.now())
.sort()[0] || null;
setIsCooldown(!!until);
};
checkCooldown();
// Update every second while in cooldown
const interval = connection.rateLimitedUntil ? setInterval(checkCooldown, 1000) : null;
const interval = modelLockUntil ? setInterval(checkCooldown, 1000) : null;
return () => {
if (interval) clearInterval(interval);
};
}, [connection.rateLimitedUntil]);
}, [modelLockUntil]);
// Determine effective status (override unavailable if cooldown expired)
const effectiveStatus = (connection.testStatus === "unavailable" && !isCooldown)
@@ -1200,7 +1208,7 @@ function ConnectionRow({ connection, isOAuth, isFirst, isLast, onMoveUp, onMoveD
<Badge variant={getStatusVariant()} size="sm" dot>
{connection.isActive === false ? "disabled" : (effectiveStatus || "Unknown")}
</Badge>
{isCooldown && connection.isActive !== false && <CooldownTimer until={connection.rateLimitedUntil} />}
{isCooldown && connection.isActive !== false && <CooldownTimer until={modelLockUntil} />}
{connection.lastError && connection.isActive !== false && (
<span className="text-xs text-red-500 truncate max-w-[300px]" title={connection.lastError}>
{connection.lastError}
@@ -1239,7 +1247,7 @@ ConnectionRow.propTypes = {
name: PropTypes.string,
email: PropTypes.string,
displayName: PropTypes.string,
rateLimitedUntil: PropTypes.string,
modelLockUntil: PropTypes.string,
testStatus: PropTypes.string,
isActive: PropTypes.bool,
lastError: PropTypes.string,
@@ -99,7 +99,8 @@ export default function ProvidersPage() {
);
const getEffectiveStatus = (conn) => {
const isCooldown = conn.rateLimitedUntil && new Date(conn.rateLimitedUntil).getTime() > Date.now();
const isCooldown = Object.entries(conn)
.some(([k, v]) => k.startsWith("modelLock_") && v && new Date(v).getTime() > Date.now());
return conn.testStatus === "unavailable" && !isCooldown ? "active" : conn.testStatus;
};