fix(providers): clear provider list when OpenClaw JSON is deleted (#526)
This commit is contained in:
committed by
GitHub
Unverified
parent
4e3f3c83f6
commit
7e54aad9e6
@@ -7,8 +7,10 @@ import type {
|
|||||||
ProviderConfig,
|
ProviderConfig,
|
||||||
ProviderDefinition,
|
ProviderDefinition,
|
||||||
} from '../../shared/providers/types';
|
} from '../../shared/providers/types';
|
||||||
|
import { BUILTIN_PROVIDER_TYPES } from '../../shared/providers/types';
|
||||||
import { ensureProviderStoreMigrated } from './provider-migration';
|
import { ensureProviderStoreMigrated } from './provider-migration';
|
||||||
import {
|
import {
|
||||||
|
deleteProviderAccount,
|
||||||
getDefaultProviderAccountId,
|
getDefaultProviderAccountId,
|
||||||
getProviderAccount,
|
getProviderAccount,
|
||||||
listProviderAccounts,
|
listProviderAccounts,
|
||||||
@@ -26,6 +28,8 @@ import {
|
|||||||
setDefaultProvider,
|
setDefaultProvider,
|
||||||
storeApiKey,
|
storeApiKey,
|
||||||
} from '../../utils/secure-storage';
|
} from '../../utils/secure-storage';
|
||||||
|
import { getActiveOpenClawProviders } from '../../utils/openclaw-auth';
|
||||||
|
import { getOpenClawProviderKeyForType } from '../../utils/provider-keys';
|
||||||
import type { ProviderWithKeyInfo } from '../../shared/providers/types';
|
import type { ProviderWithKeyInfo } from '../../shared/providers/types';
|
||||||
import { logger } from '../../utils/logger';
|
import { logger } from '../../utils/logger';
|
||||||
|
|
||||||
@@ -56,7 +60,40 @@ export class ProviderService {
|
|||||||
|
|
||||||
async listAccounts(): Promise<ProviderAccount[]> {
|
async listAccounts(): Promise<ProviderAccount[]> {
|
||||||
await ensureProviderStoreMigrated();
|
await ensureProviderStoreMigrated();
|
||||||
return listProviderAccounts();
|
const accounts = await listProviderAccounts();
|
||||||
|
|
||||||
|
// Sync check: remove stale accounts whose provider no longer exists in
|
||||||
|
// OpenClaw JSON (e.g. user deleted openclaw.json manually).
|
||||||
|
if (accounts.length > 0) {
|
||||||
|
const activeProviders = await getActiveOpenClawProviders();
|
||||||
|
const configMissing = activeProviders.size === 0;
|
||||||
|
const staleIds: string[] = [];
|
||||||
|
|
||||||
|
for (const account of accounts) {
|
||||||
|
const isBuiltin = (BUILTIN_PROVIDER_TYPES as readonly string[]).includes(account.vendorId);
|
||||||
|
const openClawKey = getOpenClawProviderKeyForType(account.vendorId, account.id);
|
||||||
|
const isActive =
|
||||||
|
activeProviders.has(account.vendorId) ||
|
||||||
|
activeProviders.has(account.id) ||
|
||||||
|
activeProviders.has(openClawKey);
|
||||||
|
|
||||||
|
// If openclaw.json is completely empty/missing, drop ALL accounts.
|
||||||
|
// Otherwise only drop non-builtin accounts that are not in the config.
|
||||||
|
if (configMissing || (!isBuiltin && !isActive)) {
|
||||||
|
staleIds.push(account.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (staleIds.length > 0) {
|
||||||
|
for (const id of staleIds) {
|
||||||
|
logger.info(`[provider-sync] Removing stale provider account "${id}" (no longer in OpenClaw config)`);
|
||||||
|
await deleteProviderAccount(id);
|
||||||
|
}
|
||||||
|
return accounts.filter((a) => !staleIds.includes(a.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return accounts;
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAccount(accountId: string): Promise<ProviderAccount | null> {
|
async getAccount(accountId: string): Promise<ProviderAccount | null> {
|
||||||
|
|||||||
@@ -267,19 +267,23 @@ export async function getAllProvidersWithKeyInfo(): Promise<
|
|||||||
const providers = await getAllProviders();
|
const providers = await getAllProviders();
|
||||||
const results: Array<ProviderConfig & { hasKey: boolean; keyMasked: string | null }> = [];
|
const results: Array<ProviderConfig & { hasKey: boolean; keyMasked: string | null }> = [];
|
||||||
const activeOpenClawProviders = await getActiveOpenClawProviders();
|
const activeOpenClawProviders = await getActiveOpenClawProviders();
|
||||||
|
// When openclaw.json is deleted/missing, the active set is empty.
|
||||||
|
// In that case, all providers (including builtins) should be cleaned up.
|
||||||
|
const configMissing = activeOpenClawProviders.size === 0;
|
||||||
|
|
||||||
for (const provider of providers) {
|
for (const provider of providers) {
|
||||||
// Sync check: If it's a custom/OAuth provider and it no longer exists in OpenClaw config
|
// Sync check: If it's a custom/OAuth provider and it no longer exists in OpenClaw config
|
||||||
// (e.g. wiped by Gateway due to missing plugin, or manually deleted by user)
|
// (e.g. wiped by Gateway due to missing plugin, or manually deleted by user)
|
||||||
// we should remove it from ClawX UI to stay consistent.
|
// we should remove it from ClawX UI to stay consistent.
|
||||||
const isBuiltin = BUILTIN_PROVIDER_TYPES.includes(provider.type);
|
const isBuiltin = (BUILTIN_PROVIDER_TYPES as readonly string[]).includes(provider.type);
|
||||||
// For custom/ollama providers, the OpenClaw config key is derived as
|
// For custom/ollama providers, the OpenClaw config key is derived as
|
||||||
// "<type>-<suffix>" where suffix = first 8 chars of providerId with hyphens stripped.
|
// "<type>-<suffix>" where suffix = first 8 chars of providerId with hyphens stripped.
|
||||||
// e.g. provider.id "custom-a1b2c3d4-..." → strip hyphens → "customa1b2c3d4..." → slice(0,8) → "customa1"
|
// e.g. provider.id "custom-a1b2c3d4-..." → strip hyphens → "customa1b2c3d4..." → slice(0,8) → "customa1"
|
||||||
// → openClawKey = "custom-customa1"
|
// → openClawKey = "custom-customa1"
|
||||||
// This must match getOpenClawProviderKey() in ipc-handlers.ts exactly.
|
// This must match getOpenClawProviderKey() in ipc-handlers.ts exactly.
|
||||||
const openClawKey = getOpenClawProviderKeyForType(provider.type, provider.id);
|
const openClawKey = getOpenClawProviderKeyForType(provider.type, provider.id);
|
||||||
if (!isBuiltin && !activeOpenClawProviders.has(provider.type) && !activeOpenClawProviders.has(provider.id) && !activeOpenClawProviders.has(openClawKey)) {
|
const isActive = activeOpenClawProviders.has(provider.type) || activeOpenClawProviders.has(provider.id) || activeOpenClawProviders.has(openClawKey);
|
||||||
|
if (configMissing || (!isBuiltin && !isActive)) {
|
||||||
console.log(`[Sync] Provider ${provider.id} (${provider.type}) missing from OpenClaw, dropping from ClawX UI`);
|
console.log(`[Sync] Provider ${provider.id} (${provider.type}) missing from OpenClaw, dropping from ClawX UI`);
|
||||||
await deleteProvider(provider.id);
|
await deleteProvider(provider.id);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
Reference in New Issue
Block a user