mirror of
https://github.com/open-webui/open-webui
synced 2025-06-26 18:26:48 +00:00
feat: model tools assignment
This commit is contained in:
@@ -74,6 +74,9 @@
|
||||
let selectedModels = [''];
|
||||
let atSelectedModel: Model | undefined;
|
||||
|
||||
let selectedModelIds = [];
|
||||
$: selectedModelIds = atSelectedModel !== undefined ? [atSelectedModel.id] : selectedModels;
|
||||
|
||||
let selectedToolIds = [];
|
||||
let webSearchEnabled = false;
|
||||
|
||||
@@ -1281,17 +1284,13 @@
|
||||
bind:selectedToolIds
|
||||
bind:webSearchEnabled
|
||||
bind:atSelectedModel
|
||||
availableTools={$user.role === 'admin'
|
||||
? $tools.reduce((a, e, i, arr) => {
|
||||
a[e.id] = {
|
||||
name: e.name,
|
||||
description: e.meta.description,
|
||||
enabled: false
|
||||
};
|
||||
|
||||
return a;
|
||||
}, {})
|
||||
: {}}
|
||||
availableToolIds={selectedModelIds.reduce((a, e, i, arr) => {
|
||||
const model = $models.find((m) => m.id === e);
|
||||
if (model?.info?.meta?.toolIds ?? false) {
|
||||
return [...new Set([...a, ...model.info.meta.toolIds])];
|
||||
}
|
||||
return a;
|
||||
}, [])}
|
||||
{selectedModels}
|
||||
{messages}
|
||||
{submitPrompt}
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
models,
|
||||
config,
|
||||
showCallOverlay,
|
||||
tools
|
||||
tools,
|
||||
user as _user
|
||||
} from '$lib/stores';
|
||||
import { blobToFile, calculateSHA256, findWordIndices } from '$lib/utils';
|
||||
|
||||
@@ -59,7 +60,7 @@
|
||||
|
||||
export let files = [];
|
||||
|
||||
export let availableTools = {};
|
||||
export let availableToolIds = [];
|
||||
export let selectedToolIds = [];
|
||||
export let webSearchEnabled = false;
|
||||
|
||||
@@ -657,7 +658,16 @@
|
||||
<InputMenu
|
||||
bind:webSearchEnabled
|
||||
bind:selectedToolIds
|
||||
tools={availableTools}
|
||||
tools={$tools.reduce((a, e, i, arr) => {
|
||||
if (availableToolIds.includes(e.id) || ($_user?.role ?? 'user') === 'admin') {
|
||||
a[e.id] = {
|
||||
name: e.name,
|
||||
description: e.meta.description,
|
||||
enabled: false
|
||||
};
|
||||
}
|
||||
return a;
|
||||
}, {})}
|
||||
uploadFilesHandler={() => {
|
||||
filesInputElement.click();
|
||||
}}
|
||||
|
||||
57
src/lib/components/workspace/Models/ToolsSelector.svelte
Normal file
57
src/lib/components/workspace/Models/ToolsSelector.svelte
Normal file
@@ -0,0 +1,57 @@
|
||||
<script lang="ts">
|
||||
import Checkbox from '$lib/components/common/Checkbox.svelte';
|
||||
import { getContext, onMount } from 'svelte';
|
||||
|
||||
export let tools = [];
|
||||
|
||||
let _tools = {};
|
||||
|
||||
export let selectedToolIds = [];
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
onMount(() => {
|
||||
_tools = tools.reduce((acc, tool) => {
|
||||
acc[tool.id] = {
|
||||
...tool,
|
||||
selected: selectedToolIds.includes(tool.id)
|
||||
};
|
||||
|
||||
return acc;
|
||||
}, {});
|
||||
});
|
||||
</script>
|
||||
|
||||
<div>
|
||||
<div class="flex w-full justify-between mb-1">
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Tools')}</div>
|
||||
</div>
|
||||
|
||||
<div class=" text-xs dark:text-gray-500">
|
||||
{$i18n.t('To select toolkits here, add them to the "Tools" workspace first.')}
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
{#if tools.length > 0}
|
||||
<div class=" flex items-center gap-2 mt-2">
|
||||
{#each Object.keys(_tools) as tool, toolIdx}
|
||||
<div class=" flex items-center gap-2">
|
||||
<div class="self-center flex items-center">
|
||||
<Checkbox
|
||||
state={_tools[tool].selected ? 'checked' : 'unchecked'}
|
||||
on:change={(e) => {
|
||||
_tools[tool].selected = e.detail === 'checked';
|
||||
selectedToolIds = Object.keys(_tools).filter((t) => _tools[t].selected);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class=" py-0.5 text-sm w-full capitalize font-medium">
|
||||
{_tools[tool].name}
|
||||
</div>
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
Reference in New Issue
Block a user