feat(channels): enhance channel configuration with account support and improve agent handling (#420)

This commit is contained in:
Haze
2026-03-11 18:44:55 +08:00
committed by GitHub
Unverified
parent 53a51642ce
commit 050ee10850
7 changed files with 388 additions and 111 deletions

View File

@@ -47,6 +47,7 @@ interface ChannelConfigModalProps {
configuredTypes?: string[];
showChannelName?: boolean;
allowExistingConfig?: boolean;
agentId?: string;
onClose: () => void;
onChannelSaved?: (channelType: ChannelType) => void | Promise<void>;
}
@@ -61,6 +62,7 @@ export function ChannelConfigModal({
configuredTypes = [],
showChannelName = true,
allowExistingConfig = true,
agentId,
onClose,
onChannelSaved,
}: ChannelConfigModalProps) {
@@ -115,8 +117,9 @@ export function ChannelConfigModal({
(async () => {
try {
const accountParam = agentId ? `?accountId=${encodeURIComponent(agentId === 'main' ? 'default' : agentId)}` : '';
const result = await hostApiFetch<{ success: boolean; values?: Record<string, string> }>(
`/api/channels/config/${encodeURIComponent(selectedType)}`
`/api/channels/config/${encodeURIComponent(selectedType)}${accountParam}`
);
if (cancelled) return;
@@ -140,7 +143,7 @@ export function ChannelConfigModal({
return () => {
cancelled = true;
};
}, [allowExistingConfig, configuredTypes, selectedType, showChannelName]);
}, [agentId, allowExistingConfig, configuredTypes, selectedType, showChannelName]);
useEffect(() => {
if (selectedType && !loadingConfig && showChannelName && firstInputRef.current) {
@@ -312,13 +315,14 @@ export function ChannelConfigModal({
}
const config: Record<string, unknown> = { ...configValues };
const resolvedAccountId = agentId ? (agentId === 'main' ? 'default' : agentId) : undefined;
const saveResult = await hostApiFetch<{
success?: boolean;
error?: string;
warning?: string;
}>('/api/channels/config', {
method: 'POST',
body: JSON.stringify({ channelType: selectedType, config }),
body: JSON.stringify({ channelType: selectedType, config, accountId: resolvedAccountId }),
});
if (!saveResult?.success) {
throw new Error(saveResult?.error || 'Failed to save channel config');

View File

@@ -535,6 +535,7 @@ function AgentSettingsModal({
configuredTypes={agent.channelTypes}
showChannelName={false}
allowExistingConfig
agentId={agent.id}
onClose={() => setShowChannelModal(false)}
onChannelSaved={async (channelType) => {
await handleChannelSaved(channelType);

View File

@@ -94,6 +94,15 @@ export function Channels() {
}
const safeChannels = Array.isArray(channels) ? channels : [];
const configuredPlaceholderChannels: Channel[] = displayedChannelTypes
.filter((type) => configuredTypes.includes(type) && !safeChannels.some((channel) => channel.type === type))
.map((type) => ({
id: `${type}-default`,
type,
name: CHANNEL_NAMES[type] || CHANNEL_META[type].name,
status: 'disconnected',
}));
const availableChannels = [...safeChannels, ...configuredPlaceholderChannels];
return (
<div className="flex flex-col -m-6 dark:bg-background h-[calc(100vh-2.5rem)] overflow-hidden">
@@ -140,13 +149,13 @@ export function Channels() {
</div>
)}
{safeChannels.length > 0 && (
{availableChannels.length > 0 && (
<div className="mb-12">
<h2 className="text-3xl font-serif text-foreground mb-6 font-normal tracking-tight" style={{ fontFamily: 'Georgia, Cambria, "Times New Roman", Times, serif' }}>
{t('availableChannels')}
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-4">
{safeChannels.map((channel) => (
{availableChannels.map((channel) => (
<ChannelCard
key={channel.id}
channel={channel}
@@ -169,9 +178,8 @@ export function Channels() {
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-6 gap-y-4">
{displayedChannelTypes.map((type) => {
const meta = CHANNEL_META[type];
const isConfigured = safeChannels.some((channel) => channel.type === type)
|| configuredTypes.includes(type);
if (isConfigured) return null;
const isAvailable = availableChannels.some((channel) => channel.type === type);
if (isAvailable) return null;
return (
<button