mirror of
https://github.com/ggml-org/llama.cpp.git
synced 2026-09-19 09:15:04 +02:00
ui: gate MCP prompt and resource capabilities on tool policy
hasPromptsCapability and hasResourcesCapability accept an optional set of usable server ids; ChatFormActions resolves it from global enablement minus the active conversation's policy. Restores the per-chat gating the old mcpServerOverrides provided; callers without arguments keep global behavior. Assisted-by: pi
This commit is contained in:
committed by
GitHub
parent
ba419bf2f1
commit
cd9d02c63f
+18
-3
@@ -11,7 +11,7 @@
|
||||
import { Button } from '$lib/components/ui/button';
|
||||
import { ICON_CLASS_DEFAULT } from '$lib/constants';
|
||||
import { setChatFormActionsContext } from '$lib/contexts';
|
||||
import { FileTypeCategory, MessageRole } from '$lib/enums';
|
||||
import { FileTypeCategory, MessageRole, ToolSource } from '$lib/enums';
|
||||
import { ChatService } from '$lib/services';
|
||||
import { chatStore, conversationsStore, mcpStore, settingsStore } from '$lib/stores';
|
||||
import { getFileTypeCategory } from '$lib/utils';
|
||||
@@ -58,9 +58,24 @@
|
||||
|
||||
let currentConfig = $derived(settingsStore.config);
|
||||
|
||||
let hasMcpPromptsSupport = $derived.by(() => mcpStore.hasPromptsCapability());
|
||||
// usable MCP servers for this conversation: globally enabled and not
|
||||
// disabled by the effective tool policy (category or server-scoped key)
|
||||
let policyEnabledMcpServerIds = $derived.by(() => {
|
||||
const prefs = conversationsStore.preferences;
|
||||
|
||||
let hasMcpResourcesSupport = $derived.by(() => mcpStore.hasResourcesCapability());
|
||||
if (!prefs.isCategoryEnabled(ToolSource.MCP)) return new Set<string>();
|
||||
|
||||
return new Set(
|
||||
mcpStore
|
||||
.getServers()
|
||||
.filter((s) => s.enabled && prefs.isServerToolsEnabled(s.id))
|
||||
.map((s) => s.id)
|
||||
);
|
||||
});
|
||||
|
||||
let hasMcpPromptsSupport = $derived(mcpStore.hasPromptsCapability(policyEnabledMcpServerIds));
|
||||
|
||||
let hasMcpResourcesSupport = $derived(mcpStore.hasResourcesCapability(policyEnabledMcpServerIds));
|
||||
|
||||
let hasAudioModality = $state(false);
|
||||
let hasVideoModality = $state(false);
|
||||
|
||||
@@ -812,19 +812,15 @@ class MCPStore implements McpHealthHost {
|
||||
* Uses health check state since servers may not have active connections until
|
||||
* the user actually sends a message or uses prompts.
|
||||
*/
|
||||
hasPromptsCapability(): boolean {
|
||||
const enabledServerIds = new Set(
|
||||
this.getServers()
|
||||
.filter((s) => s.enabled)
|
||||
.map((s) => s.id)
|
||||
);
|
||||
hasPromptsCapability(enabledServerIds?: ReadonlySet<string>): boolean {
|
||||
const ids = enabledServerIds ?? this.globalEnabledServerIds();
|
||||
|
||||
if (enabledServerIds.size === 0) {
|
||||
if (ids.size === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const [serverId, state] of Object.entries(this.health.checks)) {
|
||||
if (!enabledServerIds.has(serverId)) continue;
|
||||
if (!ids.has(serverId)) continue;
|
||||
|
||||
if (
|
||||
state.status === HealthCheckStatus.SUCCESS &&
|
||||
@@ -835,7 +831,7 @@ class MCPStore implements McpHealthHost {
|
||||
}
|
||||
|
||||
for (const [serverName, connection] of this.connections) {
|
||||
if (!enabledServerIds.has(serverName)) continue;
|
||||
if (!ids.has(serverName)) continue;
|
||||
|
||||
if (connection.serverCapabilities?.prompts) {
|
||||
return true;
|
||||
@@ -860,19 +856,15 @@ class MCPStore implements McpHealthHost {
|
||||
* Uses health check state since servers may not have active connections until
|
||||
* the user actually sends a message or uses prompts.
|
||||
*/
|
||||
hasResourcesCapability(): boolean {
|
||||
const enabledServerIds = new Set(
|
||||
this.getServers()
|
||||
.filter((s) => s.enabled)
|
||||
.map((s) => s.id)
|
||||
);
|
||||
hasResourcesCapability(enabledServerIds?: ReadonlySet<string>): boolean {
|
||||
const ids = enabledServerIds ?? this.globalEnabledServerIds();
|
||||
|
||||
if (enabledServerIds.size === 0) {
|
||||
if (ids.size === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const [serverId, state] of Object.entries(this.health.checks)) {
|
||||
if (!enabledServerIds.has(serverId)) continue;
|
||||
if (!ids.has(serverId)) continue;
|
||||
|
||||
if (
|
||||
state.status === HealthCheckStatus.SUCCESS &&
|
||||
@@ -883,7 +875,7 @@ class MCPStore implements McpHealthHost {
|
||||
}
|
||||
|
||||
for (const [serverName, connection] of this.connections) {
|
||||
if (!enabledServerIds.has(serverName)) continue;
|
||||
if (!ids.has(serverName)) continue;
|
||||
|
||||
if (MCPService.supportsResources(connection)) {
|
||||
return true;
|
||||
@@ -1341,6 +1333,15 @@ class MCPStore implements McpHealthHost {
|
||||
return `${MCP_SERVER_ID_PREFIX}-${index + 1}`;
|
||||
}
|
||||
|
||||
/** Server ids that are usable right now: globally enabled ones. */
|
||||
private globalEnabledServerIds(): Set<string> {
|
||||
return new Set(
|
||||
this.getServers()
|
||||
.filter((s) => s.enabled)
|
||||
.map((s) => s.id)
|
||||
);
|
||||
}
|
||||
|
||||
private handleToolsListChanged(serverName: string, tools: Tool[]): void {
|
||||
const connection = this.connections.get(serverName);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user