refac: user valves

This commit is contained in:
Timothy Jaeryang Baek 2025-09-26 17:49:42 -05:00
parent 807a8be299
commit b77848244b
8 changed files with 84 additions and 29 deletions

View File

@ -86,6 +86,10 @@ async def get_function_models(request):
try:
function_module = get_function_module_by_id(request, pipe.id)
has_user_valves = False
if hasattr(function_module, "UserValves"):
has_user_valves = True
# Check if function is a manifold
if hasattr(function_module, "pipes"):
sub_pipes = []
@ -124,6 +128,7 @@ async def get_function_models(request):
"created": pipe.created_at,
"owned_by": "openai",
"pipe": pipe_flag,
"has_user_valves": has_user_valves,
}
)
else:
@ -141,6 +146,7 @@ async def get_function_models(request):
"created": pipe.created_at,
"owned_by": "openai",
"pipe": pipe_flag,
"has_user_valves": has_user_valves,
}
)
except Exception as e:

View File

@ -263,6 +263,7 @@ async def get_all_models(request, refresh: bool = False, user: UserModel = None)
"icon": function.meta.manifest.get("icon_url", None)
or getattr(module, "icon_url", None)
or getattr(module, "icon", None),
"has_user_valves": hasattr(module, "UserValves"),
}
]

View File

@ -78,6 +78,8 @@
import { getSuggestionRenderer } from '../common/RichTextInput/suggestions';
import CommandSuggestionList from './MessageInput/CommandSuggestionList.svelte';
import Knobs from '../icons/Knobs.svelte';
import ValvesModal from '../workspace/common/ValvesModal.svelte';
const i18n = getContext('i18n');
@ -112,6 +114,10 @@
let inputVariables = {};
let inputVariableValues = {};
let showValvesModal = false;
let selectedValvesType = 'tool'; // 'tool' or 'function'
let selectedValvesItemId = null;
$: onChange({
prompt,
files: files
@ -932,6 +938,16 @@
onSave={inputVariablesModalCallback}
/>
<ValvesModal
bind:show={showValvesModal}
userValves={true}
type={selectedValvesType}
id={selectedValvesItemId ?? null}
on:save={async () => {
await tick();
}}
/>
{#if loaded}
<div class="w-full font-primary">
<div class=" mx-auto inset-x-0 bg-transparent flex justify-center">
@ -1449,6 +1465,12 @@
bind:webSearchEnabled
bind:imageGenerationEnabled
bind:codeInterpreterEnabled
onShowValves={(e) => {
const { type, id } = e;
selectedValvesType = type;
selectedValvesItemId = id;
showValvesModal = true;
}}
onClose={async () => {
await tick();
@ -1465,6 +1487,24 @@
</IntegrationsMenu>
{/if}
{#if selectedModelIds.length === 1 && $models.find((m) => m.id === selectedModelIds[0])?.has_user_valves}
<div class="ml-1 flex gap-1.5">
<Tooltip content={$i18n.t('Valves')} placement="top">
<button
id="model-valves-button"
class="bg-transparent hover:bg-gray-100 text-gray-700 dark:text-white dark:hover:bg-gray-800 rounded-full size-8 flex justify-center items-center outline-hidden focus:outline-hidden"
on:click={() => {
selectedValvesType = 'function';
selectedValvesItemId = selectedModelIds[0]?.split('.')[0];
showValvesModal = true;
}}
>
<Knobs className="size-4" strokeWidth="1.5" />
</button>
</Tooltip>
</div>
{/if}
<div class="ml-1 flex gap-1.5">
{#if (selectedToolIds ?? []).length > 0}
<Tooltip

View File

@ -21,7 +21,6 @@
import Terminal from '$lib/components/icons/Terminal.svelte';
import ChevronRight from '$lib/components/icons/ChevronRight.svelte';
import ChevronLeft from '$lib/components/icons/ChevronLeft.svelte';
import ValvesModal from '$lib/components/workspace/common/ValvesModal.svelte';
const i18n = getContext('i18n');
@ -41,16 +40,12 @@
export let showCodeInterpreterButton = false;
export let codeInterpreterEnabled = false;
export let onShowValves: Function;
export let onClose: Function;
let show = false;
let tab = '';
let showValvesModal = false;
let selectedValvesType = 'tool';
let selectedValvesItemId = null;
let tools = null;
$: if (show) {
@ -96,16 +91,6 @@
};
</script>
<ValvesModal
bind:show={showValvesModal}
userValves={true}
type={selectedValvesType}
id={selectedValvesItemId ?? null}
on:save={async () => {
await tick();
}}
/>
<Dropdown
bind:show
on:change={(e) => {
@ -192,6 +177,27 @@
</div>
</div>
{#if filter?.has_user_valves}
<div class=" shrink-0">
<Tooltip content={$i18n.t('Valves')}>
<button
class="self-center w-fit text-sm text-gray-600 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 transition rounded-full"
type="button"
on:click={(e) => {
e.stopPropagation();
e.preventDefault();
onShowValves({
type: 'function',
id: filter.id
});
}}
>
<Knobs />
</button>
</Tooltip>
</div>
{/if}
<div class=" shrink-0">
<Switch
state={selectedFilterIds.includes(filter.id)}
@ -364,9 +370,10 @@
on:click={(e) => {
e.stopPropagation();
e.preventDefault();
selectedValvesType = 'tool';
selectedValvesItemId = toolId;
showValvesModal = true;
onShowValves({
type: 'tool',
id: toolId
});
}}
>
<Knobs />

View File

@ -37,6 +37,7 @@
import EllipsisHorizontal from '../icons/EllipsisHorizontal.svelte';
import ChatPlus from '../icons/ChatPlus.svelte';
import ChatCheck from '../icons/ChatCheck.svelte';
import Knobs from '../icons/Knobs.svelte';
const i18n = getContext('i18n');
@ -210,7 +211,7 @@
aria-label="Controls"
>
<div class=" m-auto self-center">
<AdjustmentsHorizontal className=" size-5" strokeWidth="1" />
<Knobs className=" size-5" strokeWidth="1" />
</div>
</button>
</Tooltip>
@ -255,7 +256,7 @@
<div class="absolute top-[100%] left-0 right-0 h-fit">
{#if !history.currentId && !$chatId && ($banners.length > 0 || ($config?.license_metadata?.type ?? null) === 'trial' || (($config?.license_metadata?.seats ?? null) !== null && $config?.user_count > $config?.license_metadata?.seats))}
<div class=" w-full z-30 mt-4">
<div class=" w-full z-30">
<div class=" flex flex-col gap-1 w-full">
{#if ($config?.license_metadata?.type ?? null) === 'trial'}
<Banner

View File

@ -13,12 +13,12 @@
viewBox="0 0 24 24"
>
<!-- Top horizontal knob (left biased) -->
<line x1="3" y1="8" x2="6" y2="8" stroke-linecap="round" />
<line x1="12" y1="8" x2="21" y2="8" stroke-linecap="round" />
<circle cx="9" cy="8" r="2.5" stroke="currentColor" fill="none" />
<line x1="2" y1="7.5" x2="6" y2="7.5" stroke-linecap="round" />
<line x1="12" y1="7.5" x2="22" y2="7.5" stroke-linecap="round" />
<circle cx="9" cy="7.5" r="3" stroke="currentColor" fill="none" />
<!-- Bottom horizontal knob (right biased) -->
<line x1="3" y1="16" x2="12" y2="16" stroke-linecap="round" />
<line x1="18" y1="16" x2="21" y2="16" stroke-linecap="round" />
<circle cx="15" cy="16" r="2.5" stroke="currentColor" fill="none" />
<line x1="2" y1="16.5" x2="12" y2="16.5" stroke-linecap="round" />
<line x1="18" y1="16.5" x2="22" y2="16.5" stroke-linecap="round" />
<circle cx="15" cy="16.5" r="3" stroke="currentColor" fill="none" />
</svg>

View File

@ -91,7 +91,7 @@
{#if mounted}
{#key func?.content}
<div class="px-[16px]">
<div class="px-[16px] h-full">
<FunctionEditor
id={func?.id ?? ''}
name={func?.name ?? ''}

View File

@ -76,7 +76,7 @@
</script>
{#if func}
<div class="px-[16px]">
<div class="px-[16px] h-full">
<FunctionEditor
edit={true}
id={func.id}