llama-cpp-K2-FAST2 / tools /ui /src /lib /components /app /settings /SettingsChat /SettingsChatToolsTab.svelte
VladHong's picture
llama.cpp k2-fast2: MBZUAI model/K2Horizon + FAST2 sliding-window override
c59fd93 verified
Raw History Blame Contribute Delete
4.59 kB
<script lang="ts">
import { ChevronDown, ChevronRight } from '@lucide/svelte';
import { McpServerIdentity, TruncatedText } from '$lib/components/app';
import { Checkbox } from '$lib/components/ui/checkbox';
import * as Collapsible from '$lib/components/ui/collapsible';
import { ICON_CLASS_DEFAULT } from '$lib/constants';
import { ToolSource } from '$lib/enums/tools.enums';
import { mcpStore, permissionsStore, toolsStore } from '$lib/stores';
import { getToolUi } from '$lib/utils';
import { SvelteSet } from 'svelte/reactivity';
let expandedGroups = new SvelteSet<string>();
let groups = $derived(toolsStore.toolGroups);
function toggleExpanded(key: string) {
if (expandedGroups.has(key)) {
expandedGroups.delete(key);
} else {
expandedGroups.add(key);
}
}
</script>
{#if groups.length === 0}
<div class="py-8 text-center text-sm text-muted-foreground">No tools available</div>
{:else}
<div class="space-y-2">
<p class="text-sm text-muted-foreground">
Applies to new conversations. Tool picks inside a chat only affect that chat.
</p>
{#each groups as group (group.key)}
{@const isExpanded = expandedGroups.has(group.key)}
<Collapsible.Root onOpenChange={() => toggleExpanded(group.key)} open={isExpanded}>
<Collapsible.Trigger
class="flex w-full items-center gap-2 rounded-lg px-3 py-2 text-sm hover:bg-muted/50"
>
{#if isExpanded}
<ChevronDown class="h-3.5 w-3.5 shrink-0" />
{:else}
<ChevronRight class="h-3.5 w-3.5 shrink-0" />
{/if}
{@const isCategoryEnabled =
group.source !== ToolSource.MCP && toolsStore.isCategoryEnabled(group.source)}
{#if group.source !== ToolSource.MCP}
<Checkbox
checked={isCategoryEnabled}
onCheckedChange={() => toolsStore.toggleCategory(group.source)}
onclick={(e) => e.stopPropagation()}
/>
{/if}
{@const faviconUrl = group.serverId ? mcpStore.getServerFavicon(group.serverId) : null}
<span class="inline-flex min-w-0 items-center gap-1.5 font-medium">
{#if group.source === 'mcp'}
<McpServerIdentity
displayName={group.label}
{faviconUrl}
iconClass={ICON_CLASS_DEFAULT}
iconRounded="rounded-sm"
showVersion={false}
/>
{:else}
<TruncatedText class="font-medium" text={group.label} />
{/if}
</span>
<span class="ml-auto shrink-0 text-xs text-muted-foreground">
{group.tools.length} tool{group.tools.length !== 1 ? 's' : ''}
</span>
</Collapsible.Trigger>
<Collapsible.Content>
<div class="ml-4 border-l border-border/50 pl-2">
<!-- Header row -->
<div class="flex items-center gap-2 px-2 py-1 text-xs text-muted-foreground">
<span class="min-w-0 flex-1">Tool</span>
<span class="w-16 shrink-0 text-center">Enabled</span>
<span class="w-20 shrink-0 text-center">Always allow</span>
</div>
{#each group.tools as entry (entry.key)}
{@const toolName = entry.definition.function.name}
{@const toolUi =
entry.source === ToolSource.SERVER || entry.source === ToolSource.BROWSER
? getToolUi(toolName)
: null}
{@const displayLabel = toolUi?.label ?? toolName}
{@const IconComponent = toolUi?.icon ?? null}
{@const isEnabled = toolsStore.isToolEnabled(entry.key)}
{@const permissionKey = entry.key}
{@const isAlwaysAllowed = permissionsStore.hasTool(permissionKey)}
<div class="flex items-center gap-2 rounded px-2 py-1.5 text-sm hover:bg-muted/50">
<span class="flex min-w-0 flex-1 items-center gap-1.5">
{#if IconComponent}
<IconComponent class={ICON_CLASS_DEFAULT} />
{/if}
<TruncatedText class="min-w-0" showTooltip={true} text={displayLabel} />
</span>
<div class="flex w-16 shrink-0 justify-center">
<Checkbox
checked={isEnabled}
class={ICON_CLASS_DEFAULT}
onCheckedChange={() => toolsStore.toggleTool(entry.key)}
/>
</div>
<div class="flex w-20 shrink-0 justify-center">
<Checkbox
checked={isAlwaysAllowed}
class={ICON_CLASS_DEFAULT}
onCheckedChange={() => {
if (isAlwaysAllowed) {
permissionsStore.revokeTool(permissionKey);
} else {
permissionsStore.allowTool(permissionKey);
}
}}
/>
</div>
</div>
{/each}
</div>
</Collapsible.Content>
</Collapsible.Root>
{/each}
</div>
{/if}