char-fork/llama.cpp
git clone https://git.t4t.associates/char-fork/llama.cpp
fe235f434
char/aliceai-t5-moe
1import { CLI_FLAGS } from '$lib/constants' ; 2import { ToolSource } from '$lib/enums' ; 3import { conversationsStore , mcpStore , toolsStore } from '$lib/stores' ; 4import type { ToolEntry , ToolGroup } from '$lib/types' ; 5import { SvelteSet } from 'svelte/reactivity' ; 6 7export interface UseToolsPanelReturn { 8readonly expandedGroups :SvelteSet < string >; 9readonly categoryGroups :ToolGroup []; 10readonly mcpGroups :ToolGroup []; 11readonly totalToolCount :number ; 12readonly noToolsInfoMessage :string | null ; 13isGroupChecked ( group :ToolGroup ) :boolean ; 14getEnabledToolCount ( group :ToolGroup ) :number ; 15getGroupCheckState ( group :ToolGroup ) :{ checked :boolean ; indeterminate :boolean }; 16getFavicon ( group :ToolGroup ) :string | null ; 17isGroupDisabled ( group :ToolGroup ) :boolean ; 18isToolEnabled ( entry :ToolEntry ) :boolean ; 19isToolParentDisabled ( entry :ToolEntry ) :boolean ; 20toggleTool ( entry :ToolEntry ) :void ; 21toggleGroupExpanded ( key :string ) :void ; 22/** Toggle all tools in a group by its stable key (avoids stale group object references). */ 23toggleGroupByKey ( key :string ) :void ; 24handleOpen () :void ; 25} 26 27/** 28* Shared reactive state and helpers for the tools panel UI. 29* 30* Used by both the desktop dropdown (`ChatFormActionAddToolsSubmenu`) 31* and the mobile sheet (`ChatFormActionAddSheet`) to avoid 32* duplicating group filtering, checked-state derivation, and favicon logic. 33* 34* All toggle state routes through `conversationsStore.preferences`: with an 35* active conversation it edits that conversation's tool policy, on the 36* new-chat screen it edits the global defaults seeded into new conversations. 37*/ 38export function useToolsPanel () :UseToolsPanelReturn { 39const expandedGroups = new SvelteSet < string >(); 40const groups = $derived ( toolsStore . toolGroups ); 41// non-MCP groups are 1:1 with tool categories; MCP tools group per server 42const categoryGroups = $derived ( groups . filter (( g ) => g . source !== ToolSource . MCP )); 43const mcpGroups = $derived ( groups . filter (( g ) => g . source === ToolSource . MCP )); 44const totalToolCount = $derived ( groups . reduce (( n , g ) => n + g . tools . length , 0 )); 45const noToolsInfoMessage = $derived . by (() => { 46if ( toolsStore . loading ) return null ; 47 48if ( toolsStore . toolGroups . length > 0 ) return null ; 49 50// Tools endpoint is unreachable (404) — server started without --tools 51if ( toolsStore . isToolsEndpointUnreachable ) { 52return `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).` ; 53} 54 55// Other errors — return null so UI shows "Failed to load tools" 56if ( toolsStore . error ) return null ; 57 58return `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).` ; 59}); 60 61function isGroupChecked ( group :ToolGroup ) :boolean { 62return conversationsStore . preferences . isGroupChecked ( group ); 63} 64 65function getEnabledToolCount ( group :ToolGroup ) :number { 66return group . tools . filter (( tool ) => conversationsStore . preferences . isToolActive ( tool )). length ; 67} 68 69/** 70* Group checkbox state: checked is the parent flag (category on, or the 71* server key on for MCP groups); indeterminate marks the mixed case where 72* the parent is on but nothing or only part of the group is enabled. 73* isToolActive folds the parent gates into the count, so a disabled parent 74* always yields plain unchecked. 75*/ 76function getGroupCheckState ( group :ToolGroup ) :{ checked :boolean ; indeterminate :boolean } { 77const checked = isGroupChecked ( group ); 78const enabledCount = getEnabledToolCount ( group ); 79const indeterminate = 80group . tools . length > 0 && ( enabledCount === 0 ?checked :enabledCount < group . tools . length ); 81 82return { checked, indeterminate}; 83} 84 85function getFavicon ( group :ToolGroup ) :string | null { 86if ( group . source !== ToolSource . MCP || ! group . serverId ) return null ; 87 88return mcpStore . getServerFavicon ( group . serverId ); 89} 90 91function isGroupDisabled ( group :ToolGroup ) :boolean { 92// MCP server groups gray out while the whole MCP category is off 93return ( 94group . source === ToolSource . MCP && 95! conversationsStore . preferences . isCategoryEnabled ( ToolSource . MCP ) 96); 97} 98 99function isToolEnabled ( entry :ToolEntry ) :boolean { 100return conversationsStore . preferences . isToolEnabled ( entry . key ); 101} 102 103function isToolParentDisabled ( entry :ToolEntry ) :boolean { 104return conversationsStore . preferences . isToolParentDisabled ( entry ); 105} 106 107function toggleTool ( entry :ToolEntry ) :void { 108void conversationsStore . preferences . toggleTool ( entry . key ); 109} 110 111function toggleGroupExpanded ( key :string ) :void { 112if ( expandedGroups . has ( key )) { 113expandedGroups . delete ( key ); 114} else { 115expandedGroups . add ( key ); 116} 117} 118 119function toggleGroupByKey ( key :string ) :void { 120// Find current group by key to get up-to-date tool references 121const group = groups . find (( g ) => g . key === key ); 122 123if ( ! group ) return ; 124 125void conversationsStore . preferences . toggleGroup ( group ); 126} 127 128function handleOpen () :void { 129if ( toolsStore . serverTools . length === 0 && ! toolsStore . loading ) { 130toolsStore . fetchServerTools (); 131} 132 133mcpStore . runHealthChecksForServers ( mcpStore . getServers (). filter (( s ) => s . enabled )); 134} 135 136return { 137get categoryGroups () { 138return categoryGroups ; 139}, 140 expandedGroups, 141 getEnabledToolCount, 142 getFavicon, 143 getGroupCheckState, 144 handleOpen, 145 isGroupChecked, 146 isGroupDisabled, 147 isToolEnabled, 148 isToolParentDisabled, 149get mcpGroups () { 150return mcpGroups ; 151}, 152get noToolsInfoMessage () { 153return noToolsInfoMessage ; 154}, 155 toggleGroupByKey, 156 toggleGroupExpanded, 157 toggleTool, 158get totalToolCount () { 159return totalToolCount ; 160} 161}; 162}