fix: clean up deleted provider state correctly (#696)
This commit is contained in:
committed by
GitHub
Unverified
parent
07f3c310b5
commit
9b56d80d22
@@ -93,6 +93,82 @@ interface AuthProfilesStore {
|
||||
lastGood?: Record<string, string>;
|
||||
}
|
||||
|
||||
function removeProfilesForProvider(store: AuthProfilesStore, provider: string): boolean {
|
||||
const removedProfileIds = new Set<string>();
|
||||
|
||||
for (const [profileId, profile] of Object.entries(store.profiles)) {
|
||||
if (profile?.provider !== provider) {
|
||||
continue;
|
||||
}
|
||||
delete store.profiles[profileId];
|
||||
removedProfileIds.add(profileId);
|
||||
}
|
||||
|
||||
if (removedProfileIds.size === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (store.order) {
|
||||
for (const [orderProvider, profileIds] of Object.entries(store.order)) {
|
||||
const nextProfileIds = profileIds.filter((profileId) => !removedProfileIds.has(profileId));
|
||||
if (nextProfileIds.length > 0) {
|
||||
store.order[orderProvider] = nextProfileIds;
|
||||
} else {
|
||||
delete store.order[orderProvider];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (store.lastGood) {
|
||||
for (const [lastGoodProvider, profileId] of Object.entries(store.lastGood)) {
|
||||
if (removedProfileIds.has(profileId)) {
|
||||
delete store.lastGood[lastGoodProvider];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function removeProfileFromStore(
|
||||
store: AuthProfilesStore,
|
||||
profileId: string,
|
||||
expectedType?: AuthProfileEntry['type'] | OAuthProfileEntry['type'],
|
||||
): boolean {
|
||||
const profile = store.profiles[profileId];
|
||||
let changed = false;
|
||||
const shouldCleanReferences = !profile || !expectedType || profile.type === expectedType;
|
||||
if (profile && (!expectedType || profile.type === expectedType)) {
|
||||
delete store.profiles[profileId];
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (shouldCleanReferences && store.order) {
|
||||
for (const [orderProvider, profileIds] of Object.entries(store.order)) {
|
||||
const nextProfileIds = profileIds.filter((id) => id !== profileId);
|
||||
if (nextProfileIds.length !== profileIds.length) {
|
||||
changed = true;
|
||||
}
|
||||
if (nextProfileIds.length > 0) {
|
||||
store.order[orderProvider] = nextProfileIds;
|
||||
} else {
|
||||
delete store.order[orderProvider];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (shouldCleanReferences && store.lastGood) {
|
||||
for (const [lastGoodProvider, lastGoodProfileId] of Object.entries(store.lastGood)) {
|
||||
if (lastGoodProfileId === profileId) {
|
||||
delete store.lastGood[lastGoodProvider];
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
// ── Auth Profiles I/O ────────────────────────────────────────────
|
||||
|
||||
function getAuthProfilesPath(agentId = 'main'): string {
|
||||
@@ -346,26 +422,14 @@ export async function removeProviderKeyFromOpenClaw(
|
||||
provider: string,
|
||||
agentId?: string
|
||||
): Promise<void> {
|
||||
if (isOAuthProviderType(provider)) {
|
||||
console.log(`Skipping auth-profiles removal for OAuth provider "${provider}" (managed by OpenClaw plugin)`);
|
||||
return;
|
||||
}
|
||||
const agentIds = agentId ? [agentId] : await discoverAgentIds();
|
||||
if (agentIds.length === 0) agentIds.push('main');
|
||||
|
||||
for (const id of agentIds) {
|
||||
const store = await readAuthProfiles(id);
|
||||
const profileId = `${provider}:default`;
|
||||
|
||||
delete store.profiles[profileId];
|
||||
|
||||
if (store.order?.[provider]) {
|
||||
store.order[provider] = store.order[provider].filter((aid) => aid !== profileId);
|
||||
if (store.order[provider].length === 0) delete store.order[provider];
|
||||
if (removeProfileFromStore(store, `${provider}:default`, 'api_key')) {
|
||||
await writeAuthProfiles(store, id);
|
||||
}
|
||||
if (store.lastGood?.[provider] === profileId) delete store.lastGood[provider];
|
||||
|
||||
await writeAuthProfiles(store, id);
|
||||
}
|
||||
console.log(`Removed API key for provider "${provider}" from OpenClaw auth-profiles (agents: ${agentIds.join(', ')})`);
|
||||
}
|
||||
@@ -379,14 +443,7 @@ export async function removeProviderFromOpenClaw(provider: string): Promise<void
|
||||
if (agentIds.length === 0) agentIds.push('main');
|
||||
for (const id of agentIds) {
|
||||
const store = await readAuthProfiles(id);
|
||||
const profileId = `${provider}:default`;
|
||||
if (store.profiles[profileId]) {
|
||||
delete store.profiles[profileId];
|
||||
if (store.order?.[provider]) {
|
||||
store.order[provider] = store.order[provider].filter((aid) => aid !== profileId);
|
||||
if (store.order[provider].length === 0) delete store.order[provider];
|
||||
}
|
||||
if (store.lastGood?.[provider] === profileId) delete store.lastGood[provider];
|
||||
if (removeProfilesForProvider(store, provider)) {
|
||||
await writeAuthProfiles(store, id);
|
||||
}
|
||||
}
|
||||
@@ -435,6 +492,25 @@ export async function removeProviderFromOpenClaw(provider: string): Promise<void
|
||||
console.log(`Removed OpenClaw provider config: ${provider}`);
|
||||
}
|
||||
|
||||
const auth = (config.auth && typeof config.auth === 'object'
|
||||
? config.auth as Record<string, unknown>
|
||||
: null);
|
||||
const authProfiles = (
|
||||
auth?.profiles && typeof auth.profiles === 'object'
|
||||
? auth.profiles as Record<string, AuthProfileEntry | OAuthProfileEntry>
|
||||
: null
|
||||
);
|
||||
if (authProfiles) {
|
||||
for (const [profileId, profile] of Object.entries(authProfiles)) {
|
||||
if (profile?.provider !== provider) {
|
||||
continue;
|
||||
}
|
||||
delete authProfiles[profileId];
|
||||
modified = true;
|
||||
console.log(`Removed OpenClaw auth profile: ${profileId}`);
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up agents.defaults.model references that point to the deleted provider.
|
||||
// Model refs use the format "providerType/modelId", e.g. "openai/gpt-4".
|
||||
// Leaving stale refs causes the Gateway to report "Unknown model" errors.
|
||||
|
||||
Reference in New Issue
Block a user