mirror of
https://github.com/open-webui/open-webui
synced 2025-06-04 03:37:35 +00:00
feat: action selector
This commit is contained in:
parent
c1fd55bb04
commit
b4cd084117
60
src/lib/components/workspace/Models/ActionsSelector.svelte
Normal file
60
src/lib/components/workspace/Models/ActionsSelector.svelte
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
import { getContext, onMount } from 'svelte';
|
||||||
|
import Checkbox from '$lib/components/common/Checkbox.svelte';
|
||||||
|
import Tooltip from '$lib/components/common/Tooltip.svelte';
|
||||||
|
|
||||||
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
|
export let actions = [];
|
||||||
|
export let selectedActionIds = [];
|
||||||
|
|
||||||
|
let _actions = {};
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
_actions = actions.reduce((acc, action) => {
|
||||||
|
acc[action.id] = {
|
||||||
|
...action,
|
||||||
|
selected: selectedActionIds.includes(action.id)
|
||||||
|
};
|
||||||
|
|
||||||
|
return acc;
|
||||||
|
}, {});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<div class="flex w-full justify-between mb-1">
|
||||||
|
<div class=" self-center text-sm font-semibold">{$i18n.t('Actions')}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class=" text-xs dark:text-gray-500">
|
||||||
|
{$i18n.t('To select actions here, add them to the "Functions" workspace first.')}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- TODO: Filer order matters -->
|
||||||
|
<div class="flex flex-col">
|
||||||
|
{#if actions.length > 0}
|
||||||
|
<div class=" flex items-center mt-2 flex-wrap">
|
||||||
|
{#each Object.keys(_actions) as action, actionIdx}
|
||||||
|
<div class=" flex items-center gap-2 mr-3">
|
||||||
|
<div class="self-center flex items-center">
|
||||||
|
<Checkbox
|
||||||
|
state={_actions[action].selected ? 'checked' : 'unchecked'}
|
||||||
|
on:change={(e) => {
|
||||||
|
_actions[action].selected = e.detail === 'checked';
|
||||||
|
selectedActionIds = Object.keys(_actions).filter((t) => _actions[t].selected);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class=" py-0.5 text-sm w-full capitalize font-medium">
|
||||||
|
<Tooltip content={_actions[action].meta.description}>
|
||||||
|
{_actions[action].name}
|
||||||
|
</Tooltip>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -18,6 +18,7 @@
|
|||||||
import { stringify } from 'postcss';
|
import { stringify } from 'postcss';
|
||||||
import { parseFile } from '$lib/utils/characters';
|
import { parseFile } from '$lib/utils/characters';
|
||||||
import FiltersSelector from '$lib/components/workspace/Models/FiltersSelector.svelte';
|
import FiltersSelector from '$lib/components/workspace/Models/FiltersSelector.svelte';
|
||||||
|
import ActionsSelector from '$lib/components/workspace/Models/ActionsSelector.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
@ -63,6 +64,7 @@
|
|||||||
let toolIds = [];
|
let toolIds = [];
|
||||||
let knowledge = [];
|
let knowledge = [];
|
||||||
let filterIds = [];
|
let filterIds = [];
|
||||||
|
let actionIds = [];
|
||||||
|
|
||||||
$: if (name) {
|
$: if (name) {
|
||||||
id = name
|
id = name
|
||||||
@ -115,6 +117,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actionIds.length > 0) {
|
||||||
|
info.meta.actionIds = actionIds;
|
||||||
|
} else {
|
||||||
|
if (info.meta.actionIds) {
|
||||||
|
delete info.meta.actionIds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null;
|
info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null;
|
||||||
Object.keys(info.params).forEach((key) => {
|
Object.keys(info.params).forEach((key) => {
|
||||||
if (info.params[key] === '' || info.params[key] === null) {
|
if (info.params[key] === '' || info.params[key] === null) {
|
||||||
@ -187,6 +197,10 @@
|
|||||||
filterIds = [...model?.info?.meta?.filterIds];
|
filterIds = [...model?.info?.meta?.filterIds];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (model?.info?.meta?.actionIds) {
|
||||||
|
actionIds = [...model?.info?.meta?.actionIds];
|
||||||
|
}
|
||||||
|
|
||||||
info = {
|
info = {
|
||||||
...info,
|
...info,
|
||||||
...model.info
|
...model.info
|
||||||
@ -625,6 +639,13 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="my-2">
|
||||||
|
<ActionsSelector
|
||||||
|
bind:selectedActionIds={actionIds}
|
||||||
|
actions={$functions.filter((func) => func.type === 'action')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="my-1">
|
<div class="my-1">
|
||||||
<div class="flex w-full justify-between mb-1">
|
<div class="flex w-full justify-between mb-1">
|
||||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Capabilities')}</div>
|
<div class=" self-center text-sm font-semibold">{$i18n.t('Capabilities')}</div>
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
import Knowledge from '$lib/components/workspace/Models/Knowledge.svelte';
|
import Knowledge from '$lib/components/workspace/Models/Knowledge.svelte';
|
||||||
import ToolsSelector from '$lib/components/workspace/Models/ToolsSelector.svelte';
|
import ToolsSelector from '$lib/components/workspace/Models/ToolsSelector.svelte';
|
||||||
import FiltersSelector from '$lib/components/workspace/Models/FiltersSelector.svelte';
|
import FiltersSelector from '$lib/components/workspace/Models/FiltersSelector.svelte';
|
||||||
|
import ActionsSelector from '$lib/components/workspace/Models/ActionsSelector.svelte';
|
||||||
|
|
||||||
const i18n = getContext('i18n');
|
const i18n = getContext('i18n');
|
||||||
|
|
||||||
@ -64,6 +65,7 @@
|
|||||||
let knowledge = [];
|
let knowledge = [];
|
||||||
let toolIds = [];
|
let toolIds = [];
|
||||||
let filterIds = [];
|
let filterIds = [];
|
||||||
|
let actionIds = [];
|
||||||
|
|
||||||
const updateHandler = async () => {
|
const updateHandler = async () => {
|
||||||
loading = true;
|
loading = true;
|
||||||
@ -96,6 +98,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (actionIds.length > 0) {
|
||||||
|
info.meta.actionIds = actionIds;
|
||||||
|
} else {
|
||||||
|
if (info.meta.actionIds) {
|
||||||
|
delete info.meta.actionIds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null;
|
info.params.stop = params.stop ? params.stop.split(',').filter((s) => s.trim()) : null;
|
||||||
Object.keys(info.params).forEach((key) => {
|
Object.keys(info.params).forEach((key) => {
|
||||||
if (info.params[key] === '' || info.params[key] === null) {
|
if (info.params[key] === '' || info.params[key] === null) {
|
||||||
@ -161,6 +171,10 @@
|
|||||||
filterIds = [...model?.info?.meta?.filterIds];
|
filterIds = [...model?.info?.meta?.filterIds];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (model?.info?.meta?.actionIds) {
|
||||||
|
actionIds = [...model?.info?.meta?.actionIds];
|
||||||
|
}
|
||||||
|
|
||||||
if (model?.owned_by === 'openai') {
|
if (model?.owned_by === 'openai') {
|
||||||
capabilities.usage = false;
|
capabilities.usage = false;
|
||||||
}
|
}
|
||||||
@ -555,6 +569,13 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="my-2">
|
||||||
|
<ActionsSelector
|
||||||
|
bind:selectedActionIds={actionIds}
|
||||||
|
actions={$functions.filter((func) => func.type === 'action')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="my-2">
|
<div class="my-2">
|
||||||
<div class="flex w-full justify-between mb-1">
|
<div class="flex w-full justify-between mb-1">
|
||||||
<div class=" self-center text-sm font-semibold">{$i18n.t('Capabilities')}</div>
|
<div class=" self-center text-sm font-semibold">{$i18n.t('Capabilities')}</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user