ggml-org/llama.cpp · #28646

webui: stop re-probing disabled /tools endpoint on every message

geckguy · merged Sep 14, 20263 files · 12 + / 9
tools/ui/src/lib/hooks/use-tools-panel.svelte.ts1 + / 1
@@ -47,7 +47,7 @@ export function useToolsPanel(): UseToolsPanelReturn {  		if (toolsStore.toolGroups.length > 0) return null; -		// Tools endpoint is unreachable (404) — server started without --tools+		// Tools endpoint unreachable (403) — server started without tools 		if (toolsStore.isToolsEndpointUnreachable) { 			return `To enable Server Tools you need to run llama-server with ${CLI_FLAGS.TOOLS} all or ${CLI_FLAGS.TOOLS} <name> flag. To see MCP Tools you need to add / enable MCP Server(s).`; 		}
tools/ui/src/lib/stores/agentic/index.svelte.ts8 + / 2
@@ -315,8 +315,14 @@ class AgenticStore { 		// Clear any pending permissions/continue requests for this conversation when starting a new flow 		this.gates.clear(conversationId); -		// Ensure server tools are fetched before checking if agentic is enabled-		if (toolsStore.serverTools.length === 0 && !toolsStore.loading) {+		// Ensure server tools are fetched before checking if agentic is enabled.+		// A disabled /tools endpoint stays disabled for the life of the server,+		// so the tools panel is the only place that probes it again.+		if (+			toolsStore.serverTools.length === 0 &&+			!toolsStore.loading &&+			!toolsStore.isToolsEndpointUnreachable+		) { 			await toolsStore.fetchServerTools(); 		} 
tools/ui/src/lib/stores/tools.svelte.ts3 + / 6
@@ -32,7 +32,7 @@ import { mcpStore } from '$lib/stores/mcp/index.svelte'; import { modelsStore } from '$lib/stores/models/index.svelte'; import { settingsStore } from '$lib/stores/settings/index.svelte'; import type { OpenAIToolDefinition, ToolEntry, ToolGroup } from '$lib/types';-import { buildSandboxToolDefinition } from '$lib/utils';+import { ApiError, buildSandboxToolDefinition } from '$lib/utils'; import { SvelteMap, SvelteSet } from 'svelte/reactivity';  /** Stable selection identity for a tool, shared by the disabled set and the permission store */@@ -246,13 +246,10 @@ class ToolsStore { 				toolInfos.filter((info) => info.uses_cwd).map((info) => info.tool) 			); 		} catch (err) {-			const errorMessage = err instanceof Error ? err.message : String(err);--			this._error = errorMessage;+			this._error = err instanceof Error ? err.message : String(err);  			// 403 from /tools means the server was started without --tools-			// TODO: check status code instead of relying on message-			if (errorMessage.includes('this feature is disabled')) {+			if (err instanceof ApiError && err.status === 403) { 				this._toolsEndpointUnreachable = true; 				console.info('[ToolsStore] Server tools are disabled on the server'); 			} else {