enh: builtin tools model editor
This commit is contained in:
@@ -402,34 +402,43 @@ def get_builtin_tools(
|
||||
.get(name, default)
|
||||
)
|
||||
|
||||
# Time utilities - always available for date calculations
|
||||
builtin_functions.extend([get_current_timestamp, calculate_timestamp])
|
||||
# Helper to check if a builtin tool category is enabled via meta.builtinTools
|
||||
# Defaults to True if not specified (backward compatible)
|
||||
def is_builtin_tool_enabled(category: str) -> bool:
|
||||
builtin_tools = model.get("info", {}).get("meta", {}).get("builtinTools", {})
|
||||
return builtin_tools.get(category, True)
|
||||
|
||||
# Time utilities - available for date calculations
|
||||
if is_builtin_tool_enabled("time"):
|
||||
builtin_functions.extend([get_current_timestamp, calculate_timestamp])
|
||||
|
||||
# Knowledge base tools - conditional injection based on model knowledge
|
||||
# If model has attached knowledge (any type), only provide query_knowledge_files
|
||||
# Otherwise, provide all KB browsing tools
|
||||
model_knowledge = model.get("info", {}).get("meta", {}).get("knowledge", [])
|
||||
if model_knowledge:
|
||||
# Model has attached knowledge - only allow semantic search within it
|
||||
builtin_functions.append(query_knowledge_files)
|
||||
else:
|
||||
# No model knowledge - allow full KB browsing
|
||||
builtin_functions.extend(
|
||||
[
|
||||
list_knowledge_bases,
|
||||
search_knowledge_bases,
|
||||
query_knowledge_bases,
|
||||
search_knowledge_files,
|
||||
query_knowledge_files,
|
||||
view_knowledge_file,
|
||||
]
|
||||
)
|
||||
if is_builtin_tool_enabled("knowledge"):
|
||||
if model_knowledge:
|
||||
# Model has attached knowledge - only allow semantic search within it
|
||||
builtin_functions.append(query_knowledge_files)
|
||||
else:
|
||||
# No model knowledge - allow full KB browsing
|
||||
builtin_functions.extend(
|
||||
[
|
||||
list_knowledge_bases,
|
||||
search_knowledge_bases,
|
||||
query_knowledge_bases,
|
||||
search_knowledge_files,
|
||||
query_knowledge_files,
|
||||
view_knowledge_file,
|
||||
]
|
||||
)
|
||||
|
||||
# Chats tools - search and fetch user's chat history
|
||||
builtin_functions.extend([search_chats, view_chat])
|
||||
if is_builtin_tool_enabled("chats"):
|
||||
builtin_functions.extend([search_chats, view_chat])
|
||||
|
||||
# Add memory tools if enabled for this chat
|
||||
if features.get("memory"):
|
||||
# Add memory tools if builtin category enabled AND enabled for this chat
|
||||
if is_builtin_tool_enabled("memory") and features.get("memory"):
|
||||
builtin_functions.extend([search_memories, add_memory, replace_memory_content])
|
||||
|
||||
# Add web search tools if enabled globally AND model has web_search capability
|
||||
@@ -456,14 +465,14 @@ def get_builtin_tools(
|
||||
):
|
||||
builtin_functions.append(execute_code)
|
||||
|
||||
# Notes tools - search, view, create, and update user's notes (if notes enabled globally)
|
||||
if getattr(request.app.state.config, "ENABLE_NOTES", False):
|
||||
# Notes tools - search, view, create, and update user's notes (if builtin category enabled AND notes enabled globally)
|
||||
if is_builtin_tool_enabled("notes") and getattr(request.app.state.config, "ENABLE_NOTES", False):
|
||||
builtin_functions.extend(
|
||||
[search_notes, view_note, write_note, replace_note_content]
|
||||
)
|
||||
|
||||
# Channels tools - search channels and messages (if channels enabled globally)
|
||||
if getattr(request.app.state.config, "ENABLE_CHANNELS", False):
|
||||
# Channels tools - search channels and messages (if builtin category enabled AND channels enabled globally)
|
||||
if is_builtin_tool_enabled("channels") and getattr(request.app.state.config, "ENABLE_CHANNELS", False):
|
||||
builtin_functions.extend(
|
||||
[
|
||||
search_channels,
|
||||
|
||||
75
src/lib/components/workspace/Models/BuiltinTools.svelte
Normal file
75
src/lib/components/workspace/Models/BuiltinTools.svelte
Normal file
@@ -0,0 +1,75 @@
|
||||
<script lang="ts">
|
||||
import { getContext } from 'svelte';
|
||||
import Checkbox from '$lib/components/common/Checkbox.svelte';
|
||||
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||
import { marked } from 'marked';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
const toolLabels = {
|
||||
time: {
|
||||
label: $i18n.t('Time & Calculation'),
|
||||
description: $i18n.t('Get current time and perform date/time calculations')
|
||||
},
|
||||
memory: {
|
||||
label: $i18n.t('Memory'),
|
||||
description: $i18n.t('Search and manage user memories')
|
||||
},
|
||||
chats: {
|
||||
label: $i18n.t('Chat History'),
|
||||
description: $i18n.t('Search and view user chat history')
|
||||
},
|
||||
notes: {
|
||||
label: $i18n.t('Notes'),
|
||||
description: $i18n.t('Search, view, and manage user notes')
|
||||
},
|
||||
knowledge: {
|
||||
label: $i18n.t('Knowledge Base'),
|
||||
description: $i18n.t('Browse and query knowledge bases')
|
||||
},
|
||||
channels: {
|
||||
label: $i18n.t('Channels'),
|
||||
description: $i18n.t('Search channels and channel messages')
|
||||
}
|
||||
};
|
||||
|
||||
const allTools = Object.keys(toolLabels);
|
||||
|
||||
export let builtinTools: Record<string, boolean> = {};
|
||||
|
||||
// Initialize missing keys to true (default enabled)
|
||||
$: {
|
||||
for (const tool of allTools) {
|
||||
if (!(tool in builtinTools)) {
|
||||
builtinTools[tool] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div class="flex w-full justify-between mb-1">
|
||||
<div class="self-center text-xs font-medium text-gray-500">{$i18n.t('Builtin Tools')}</div>
|
||||
</div>
|
||||
<div class="flex items-center mt-2 flex-wrap">
|
||||
{#each allTools as tool}
|
||||
<div class="flex items-center gap-2 mr-3">
|
||||
<Checkbox
|
||||
state={builtinTools[tool] !== false ? 'checked' : 'unchecked'}
|
||||
on:change={(e) => {
|
||||
builtinTools = {
|
||||
...builtinTools,
|
||||
[tool]: e.detail === 'checked'
|
||||
};
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="py-0.5 text-sm">
|
||||
<Tooltip content={marked.parse(toolLabels[tool].description)}>
|
||||
{$i18n.t(toolLabels[tool].label)}
|
||||
</Tooltip>
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
@@ -21,6 +21,7 @@
|
||||
import XMark from '$lib/components/icons/XMark.svelte';
|
||||
import DefaultFiltersSelector from './DefaultFiltersSelector.svelte';
|
||||
import DefaultFeatures from './DefaultFeatures.svelte';
|
||||
import BuiltinTools from './BuiltinTools.svelte';
|
||||
import PromptSuggestions from './PromptSuggestions.svelte';
|
||||
import AccessControlModal from '../common/AccessControlModal.svelte';
|
||||
import LockClosed from '$lib/components/icons/LockClosed.svelte';
|
||||
@@ -104,6 +105,7 @@
|
||||
builtin_tools: true
|
||||
};
|
||||
let defaultFeatureIds = [];
|
||||
let builtinTools = {};
|
||||
|
||||
let actionIds = [];
|
||||
let accessControl = {};
|
||||
@@ -195,6 +197,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(builtinTools).length > 0) {
|
||||
info.meta.builtinTools = builtinTools;
|
||||
} else {
|
||||
if (info.meta.builtinTools) {
|
||||
delete info.meta.builtinTools;
|
||||
}
|
||||
}
|
||||
|
||||
if (tts.voice !== '') {
|
||||
if (!info.meta.tts) info.meta.tts = {};
|
||||
info.meta.tts.voice = tts.voice;
|
||||
@@ -288,6 +298,7 @@
|
||||
|
||||
capabilities = { ...capabilities, ...(model?.meta?.capabilities ?? {}) };
|
||||
defaultFeatureIds = model?.meta?.defaultFeatureIds ?? [];
|
||||
builtinTools = model?.meta?.builtinTools ?? {};
|
||||
tts = { voice: model?.meta?.tts?.voice ?? '' };
|
||||
|
||||
if ('access_control' in model) {
|
||||
@@ -780,6 +791,12 @@
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
{#if capabilities.builtin_tools}
|
||||
<div class="my-2">
|
||||
<BuiltinTools bind:builtinTools />
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between mb-1">
|
||||
<div class="self-center text-xs font-medium text-gray-500">
|
||||
|
||||
Reference in New Issue
Block a user