diff --git a/ui/src/components/cliproxy/provider-editor/account-item.tsx b/ui/src/components/cliproxy/provider-editor/account-item.tsx
index 0ef2c276..e12d1a29 100644
--- a/ui/src/components/cliproxy/provider-editor/account-item.tsx
+++ b/ui/src/components/cliproxy/provider-editor/account-item.tsx
@@ -22,6 +22,8 @@ import {
Loader2,
CheckCircle2,
HelpCircle,
+ Pause,
+ Play,
} from 'lucide-react';
import {
cn,
@@ -86,6 +88,7 @@ export function AccountItem({
account,
onSetDefault,
onRemove,
+ onPauseToggle,
isRemoving,
privacyMode,
showQuota,
@@ -139,6 +142,28 @@ export function AccountItem({
Default
)}
+ {account.tier && account.tier !== 'unknown' && (
+
+ {account.tier}
+
+ )}
+ {account.paused && (
+
+
+ Paused
+
+ )}
{account.lastUsedAt && (
@@ -162,6 +187,21 @@ export function AccountItem({
Set as default
)}
+ {onPauseToggle && (
+
onPauseToggle(!account.paused)}>
+ {account.paused ? (
+ <>
+
+ Resume account
+ >
+ ) : (
+ <>
+
+ Pause account
+ >
+ )}
+
+ )}
void;
onSetDefault: (accountId: string) => void;
onRemoveAccount: (accountId: string) => void;
+ onPauseToggle?: (accountId: string, paused: boolean) => void;
isRemovingAccount?: boolean;
privacyMode?: boolean;
/** Show quota bars for accounts (only applicable for 'agy' provider) */
@@ -31,6 +32,7 @@ export function AccountsSection({
onAddAccount,
onSetDefault,
onRemoveAccount,
+ onPauseToggle,
isRemovingAccount,
privacyMode,
showQuota,
@@ -65,6 +67,9 @@ export function AccountsSection({
account={account}
onSetDefault={() => onSetDefault(account.id)}
onRemove={() => onRemoveAccount(account.id)}
+ onPauseToggle={
+ onPauseToggle ? (paused) => onPauseToggle(account.id, paused) : undefined
+ }
isRemoving={isRemovingAccount}
privacyMode={privacyMode}
showQuota={showQuota}
diff --git a/ui/src/components/cliproxy/provider-editor/index.tsx b/ui/src/components/cliproxy/provider-editor/index.tsx
index 53338e3c..1cc552fa 100644
--- a/ui/src/components/cliproxy/provider-editor/index.tsx
+++ b/ui/src/components/cliproxy/provider-editor/index.tsx
@@ -38,6 +38,7 @@ export function ProviderEditor({
onAddAccount,
onSetDefault,
onRemoveAccount,
+ onPauseToggle,
isRemovingAccount,
}: ProviderEditorProps) {
const [customPresetOpen, setCustomPresetOpen] = useState(false);
@@ -200,6 +201,7 @@ export function ProviderEditor({
onAddAccount={onAddAccount}
onSetDefault={onSetDefault}
onRemoveAccount={onRemoveAccount}
+ onPauseToggle={onPauseToggle}
isRemovingAccount={isRemovingAccount}
privacyMode={privacyMode}
isRemoteMode={isRemoteMode}
diff --git a/ui/src/components/cliproxy/provider-editor/model-config-tab.tsx b/ui/src/components/cliproxy/provider-editor/model-config-tab.tsx
index a8552eb2..25ca0306 100644
--- a/ui/src/components/cliproxy/provider-editor/model-config-tab.tsx
+++ b/ui/src/components/cliproxy/provider-editor/model-config-tab.tsx
@@ -36,6 +36,7 @@ interface ModelConfigTabProps {
onAddAccount: () => void;
onSetDefault: (accountId: string) => void;
onRemoveAccount: (accountId: string) => void;
+ onPauseToggle?: (accountId: string, paused: boolean) => void;
isRemovingAccount?: boolean;
privacyMode?: boolean;
/** True if connected to remote CLIProxy (quota not available) */
@@ -60,6 +61,7 @@ export function ModelConfigTab({
onAddAccount,
onSetDefault,
onRemoveAccount,
+ onPauseToggle,
isRemovingAccount,
privacyMode,
isRemoteMode,
@@ -134,6 +136,7 @@ export function ModelConfigTab({
onAddAccount={onAddAccount}
onSetDefault={onSetDefault}
onRemoveAccount={onRemoveAccount}
+ onPauseToggle={onPauseToggle}
isRemovingAccount={isRemovingAccount}
privacyMode={privacyMode}
showQuota={provider === 'agy' && !isRemoteMode}
diff --git a/ui/src/components/cliproxy/provider-editor/types.ts b/ui/src/components/cliproxy/provider-editor/types.ts
index 52e5a7d6..80010f9f 100644
--- a/ui/src/components/cliproxy/provider-editor/types.ts
+++ b/ui/src/components/cliproxy/provider-editor/types.ts
@@ -30,6 +30,7 @@ export interface ProviderEditorProps {
onAddAccount: () => void;
onSetDefault: (accountId: string) => void;
onRemoveAccount: (accountId: string) => void;
+ onPauseToggle?: (accountId: string, paused: boolean) => void;
isRemovingAccount?: boolean;
}
@@ -37,6 +38,7 @@ export interface AccountItemProps {
account: OAuthAccount;
onSetDefault: () => void;
onRemove: () => void;
+ onPauseToggle?: (paused: boolean) => void;
isRemoving?: boolean;
privacyMode?: boolean;
/** Show quota bar (only for 'agy' provider) */
diff --git a/ui/src/pages/cliproxy.tsx b/ui/src/pages/cliproxy.tsx
index 872e3832..bd13b9dc 100644
--- a/ui/src/pages/cliproxy.tsx
+++ b/ui/src/pages/cliproxy.tsx
@@ -21,6 +21,8 @@ import {
useCliproxyAuth,
useSetDefaultAccount,
useRemoveAccount,
+ usePauseAccount,
+ useResumeAccount,
useDeleteVariant,
} from '@/hooks/use-cliproxy';
import type { AuthStatus, Variant } from '@/lib/api-client';
@@ -179,6 +181,8 @@ export function CliproxyPage() {
const { data: variantsData, isFetching } = useCliproxy();
const setDefaultMutation = useSetDefaultAccount();
const removeMutation = useRemoveAccount();
+ const pauseMutation = usePauseAccount();
+ const resumeMutation = useResumeAccount();
const deleteMutation = useDeleteVariant();
// Selection state: either a provider or a variant
@@ -216,6 +220,14 @@ export function CliproxyPage() {
queryClient.invalidateQueries({ queryKey: ['cliproxy-auth'] });
};
+ const handlePauseToggle = (provider: string, accountId: string, paused: boolean) => {
+ if (paused) {
+ pauseMutation.mutate({ provider, accountId });
+ } else {
+ resumeMutation.mutate({ provider, accountId });
+ }
+ };
+
const handleSelectProvider = (provider: string) => {
setSelectedProvider(provider);
setSelectedVariant(null);
@@ -361,6 +373,9 @@ export function CliproxyPage() {
accountId,
})
}
+ onPauseToggle={(accountId, paused) =>
+ handlePauseToggle(selectedVariantData.provider, accountId, paused)
+ }
isRemovingAccount={removeMutation.isPending}
/>
) : selectedStatus ? (
@@ -389,6 +404,9 @@ export function CliproxyPage() {
accountId,
})
}
+ onPauseToggle={(accountId, paused) =>
+ handlePauseToggle(selectedStatus.provider, accountId, paused)
+ }
isRemovingAccount={removeMutation.isPending}
/>
) : (