mirror of
https://github.com/open-webui/open-webui
synced 2025-02-20 12:00:22 +00:00
feat: model tools assignment
This commit is contained in:
parent
c3ce4d7f6a
commit
5cd28c04b8
@ -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>
|
@ -2,7 +2,7 @@
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { toast } from 'svelte-sonner';
|
||||
import { goto } from '$app/navigation';
|
||||
import { settings, user, config, models } from '$lib/stores';
|
||||
import { settings, user, config, models, tools } from '$lib/stores';
|
||||
|
||||
import { onMount, tick, getContext } from 'svelte';
|
||||
import { addNewModel, getModelById, getModelInfos } from '$lib/apis/models';
|
||||
@ -12,6 +12,8 @@
|
||||
import Checkbox from '$lib/components/common/Checkbox.svelte';
|
||||
import Tags from '$lib/components/common/Tags.svelte';
|
||||
import Knowledge from '$lib/components/workspace/Models/Knowledge.svelte';
|
||||
import ToolsSelector from '$lib/components/workspace/Models/ToolsSelector.svelte';
|
||||
import { stringify } from 'postcss';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
@ -54,6 +56,7 @@
|
||||
vision: true
|
||||
};
|
||||
|
||||
let toolIds = [];
|
||||
let knowledge = [];
|
||||
|
||||
$: if (name) {
|
||||
@ -88,6 +91,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (toolIds.length > 0) {
|
||||
info.meta.toolIds = toolIds;
|
||||
} else {
|
||||
if (info.meta.toolIds) {
|
||||
delete info.meta.toolIds;
|
||||
}
|
||||
}
|
||||
|
||||
info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null;
|
||||
Object.keys(info.params).forEach((key) => {
|
||||
if (info.params[key] === '' || info.params[key] === null) {
|
||||
@ -154,6 +165,7 @@
|
||||
params.stop = params?.stop ? (params?.stop ?? []).join(',') : null;
|
||||
|
||||
capabilities = { ...capabilities, ...(model?.info?.meta?.capabilities ?? {}) };
|
||||
toolIds = model?.info?.meta?.toolIds ?? [];
|
||||
|
||||
info = {
|
||||
...info,
|
||||
@ -554,6 +566,10 @@
|
||||
<Knowledge bind:knowledge />
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<ToolsSelector bind:selectedToolIds={toolIds} tools={$tools} />
|
||||
</div>
|
||||
|
||||
<div class="my-1">
|
||||
<div class="flex w-full justify-between mb-1">
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Capabilities')}</div>
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
import { onMount, getContext } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { settings, user, config, models } from '$lib/stores';
|
||||
import { settings, user, config, models, tools } from '$lib/stores';
|
||||
import { splitStream } from '$lib/utils';
|
||||
|
||||
import { getModelInfos, updateModelById } from '$lib/apis/models';
|
||||
@ -15,6 +15,7 @@
|
||||
import Checkbox from '$lib/components/common/Checkbox.svelte';
|
||||
import Tags from '$lib/components/common/Tags.svelte';
|
||||
import Knowledge from '$lib/components/workspace/Models/Knowledge.svelte';
|
||||
import ToolsSelector from '$lib/components/workspace/Models/ToolsSelector.svelte';
|
||||
|
||||
const i18n = getContext('i18n');
|
||||
|
||||
@ -60,6 +61,7 @@
|
||||
};
|
||||
|
||||
let knowledge = [];
|
||||
let toolIds = [];
|
||||
|
||||
const updateHandler = async () => {
|
||||
loading = true;
|
||||
@ -76,6 +78,14 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (toolIds.length > 0) {
|
||||
info.meta.toolIds = toolIds;
|
||||
} else {
|
||||
if (info.meta.toolIds) {
|
||||
delete info.meta.toolIds;
|
||||
}
|
||||
}
|
||||
|
||||
info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null;
|
||||
Object.keys(info.params).forEach((key) => {
|
||||
if (info.params[key] === '' || info.params[key] === null) {
|
||||
@ -133,6 +143,10 @@
|
||||
knowledge = [...model?.info?.meta?.knowledge];
|
||||
}
|
||||
|
||||
if (model?.info?.meta?.toolIds) {
|
||||
toolIds = [...model?.info?.meta?.toolIds];
|
||||
}
|
||||
|
||||
if (model?.owned_by === 'openai') {
|
||||
capabilities.usage = false;
|
||||
}
|
||||
@ -515,6 +529,10 @@
|
||||
<Knowledge bind:knowledge />
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<ToolsSelector bind:selectedToolIds={toolIds} tools={$tools} />
|
||||
</div>
|
||||
|
||||
<div class="my-2">
|
||||
<div class="flex w-full justify-between mb-1">
|
||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Capabilities')}</div>
|
||||
|
Loading…
Reference in New Issue
Block a user