fix(channel): support channel names that include numbers; legacy test names containing numbers may still appear (#796)

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Haze <hazeone@users.noreply.github.com>
This commit is contained in:
Haze
2026-04-08 18:38:59 +08:00
committed by GitHub
Unverified
parent 19b3ea974b
commit c1e165d48d
6 changed files with 219 additions and 29 deletions

View File

@@ -317,6 +317,20 @@ interface ChannelAccountsView {
accounts: ChannelAccountView[];
}
function shouldIncludeRuntimeAccountId(
accountId: string,
configuredAccountIds: Set<string>,
runtimeAccount: { configured?: boolean },
): boolean {
if (configuredAccountIds.has(accountId)) {
return true;
}
// Defensive filtering: channels.status can occasionally expose transient
// runtime rows for stale sessions. Only include runtime-only accounts when
// gateway marks them as configured.
return runtimeAccount.configured === true;
}
interface ChannelTargetOptionView {
value: string;
label: string;
@@ -375,6 +389,7 @@ async function buildChannelAccountsView(ctx: HostApiContext): Promise<ChannelAcc
for (const rawChannelType of channelTypes) {
const uiChannelType = toUiChannelType(rawChannelType);
const channelAccountsFromConfig = configuredAccounts[rawChannelType]?.accountIds ?? [];
const configuredAccountIdSet = new Set(channelAccountsFromConfig);
const hasLocalConfig = configuredChannels.includes(rawChannelType) || Boolean(configuredAccounts[rawChannelType]);
const channelSection = openClawConfig.channels?.[rawChannelType];
const channelSummary =
@@ -396,9 +411,17 @@ async function buildChannelAccountsView(ctx: HostApiContext): Promise<ChannelAcc
if (!hasLocalConfig && !hasRuntimeConfigured) {
continue;
}
const runtimeAccountIds = runtimeAccounts
.map((account) => account.accountId)
.filter((accountId): accountId is string => typeof accountId === 'string' && accountId.trim().length > 0);
const runtimeAccountIds = runtimeAccounts.reduce<string[]>((acc, account) => {
const accountId = typeof account.accountId === 'string' ? account.accountId.trim() : '';
if (!accountId) {
return acc;
}
if (!shouldIncludeRuntimeAccountId(accountId, configuredAccountIdSet, account)) {
return acc;
}
acc.push(accountId);
return acc;
}, []);
const accountIds = Array.from(new Set([...channelAccountsFromConfig, ...runtimeAccountIds, defaultAccountId]));
const accounts: ChannelAccountView[] = accountIds.map((accountId) => {