feat: Enhance Keep-Alive configuration handling (#455)

This commit is contained in:
samanhappy
2025-11-30 09:59:48 +08:00
committed by GitHub
parent 063b081297
commit 8770b9ccfe
14 changed files with 234 additions and 175 deletions

View File

@@ -95,6 +95,11 @@ const ServerForm = ({
undefined,
},
oauth: getInitialOAuthConfig(initialData),
// KeepAlive configuration initialization
keepAlive: {
enabled: initialData?.config?.enableKeepAlive || false,
interval: initialData?.config?.keepAliveInterval || 60000,
},
// OpenAPI configuration initialization
openapi:
initialData && initialData.config && initialData.config.openapi
@@ -151,6 +156,7 @@ const ServerForm = ({
const [isRequestOptionsExpanded, setIsRequestOptionsExpanded] = useState<boolean>(false);
const [isOAuthSectionExpanded, setIsOAuthSectionExpanded] = useState<boolean>(false);
const [isKeepAliveSectionExpanded, setIsKeepAliveSectionExpanded] = useState<boolean>(false);
const [error, setError] = useState<string | null>(null);
const isEdit = !!initialData;
@@ -377,6 +383,15 @@ const ServerForm = ({
env: Object.keys(env).length > 0 ? env : undefined,
}),
...(Object.keys(options).length > 0 ? { options } : {}),
// KeepAlive configuration (only for SSE/streamable-http types)
...(serverType === 'sse' || serverType === 'streamable-http'
? {
enableKeepAlive: formData.keepAlive?.enabled || false,
...(formData.keepAlive?.enabled
? { keepAliveInterval: formData.keepAlive.interval || 60000 }
: {}),
}
: {}),
},
};
@@ -1255,6 +1270,86 @@ const ServerForm = ({
</div>
)}
{/* KeepAlive Configuration - only for SSE/Streamable HTTP */}
{(serverType === 'sse' || serverType === 'streamable-http') && (
<div className="mb-4">
<div
className="flex items-center justify-between cursor-pointer bg-gray-50 hover:bg-gray-100 p-3 rounded border border-gray-200"
onClick={() => setIsKeepAliveSectionExpanded(!isKeepAliveSectionExpanded)}
>
<label className="text-gray-700 text-sm font-bold">
{t('server.keepAlive', 'Keep-Alive')}
</label>
<span className="text-gray-500 text-sm">
{isKeepAliveSectionExpanded ? '▼' : '▶'}
</span>
</div>
{isKeepAliveSectionExpanded && (
<div className="border border-gray-200 rounded-b p-4 bg-gray-50 border-t-0">
<div className="flex items-center mb-3">
<input
type="checkbox"
id="enableKeepAlive"
checked={formData.keepAlive?.enabled || false}
onChange={(e) =>
setFormData((prev) => ({
...prev,
keepAlive: {
...prev.keepAlive,
enabled: e.target.checked,
},
}))
}
className="mr-2"
/>
<label htmlFor="enableKeepAlive" className="text-gray-600 text-sm">
{t('server.enableKeepAlive', 'Enable Keep-Alive')}
</label>
</div>
<p className="text-xs text-gray-500 mb-3">
{t(
'server.keepAliveDescription',
'Send periodic ping requests to maintain the connection. Useful for long-running connections that may timeout.',
)}
</p>
<div>
<label
className="block text-gray-600 text-sm font-medium mb-1"
htmlFor="keepAliveInterval"
>
{t('server.keepAliveInterval', 'Interval (ms)')}
</label>
<input
type="number"
id="keepAliveInterval"
value={formData.keepAlive?.interval || 60000}
onChange={(e) =>
setFormData((prev) => ({
...prev,
keepAlive: {
...prev.keepAlive,
interval: parseInt(e.target.value) || 60000,
},
}))
}
className="shadow appearance-none border rounded w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline form-input"
placeholder="60000"
min="5000"
max="300000"
/>
<p className="text-xs text-gray-500 mt-1">
{t(
'server.keepAliveIntervalDescription',
'Time between keep-alive pings in milliseconds (default: 60000ms = 1 minute)',
)}
</p>
</div>
</div>
)}
</div>
)}
<div className="flex justify-end mt-6">
<button
type="button"

View File

@@ -114,6 +114,8 @@ export interface ServerConfig {
env?: Record<string, string>;
headers?: Record<string, string>;
enabled?: boolean;
enableKeepAlive?: boolean; // Enable keep-alive for this server (requires global enable as well)
keepAliveInterval?: number; // Keep-alive ping interval in milliseconds (default: 60000ms)
tools?: Record<string, { enabled: boolean; description?: string }>; // Tool-specific configurations with enable/disable state and custom descriptions
prompts?: Record<string, { enabled: boolean; description?: string }>; // Prompt-specific configurations with enable/disable state and custom descriptions
options?: {
@@ -250,6 +252,10 @@ export interface ServerFormData {
resetTimeoutOnProgress?: boolean;
maxTotalTimeout?: number;
};
keepAlive?: {
enabled?: boolean;
interval?: number;
};
oauth?: {
clientId?: string;
clientSecret?: string;