From 62fc436999ad32e82d1405ac14d1f03e0f0341ec Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 16 Aug 2026 22:52:24 -0700 Subject: [PATCH] refac --- backend/open_webui/utils/tool_approval.py | 6 ++- src/lib/components/chat/Chat.svelte | 50 ++++++++++++++++++++++- 2 files changed, 54 insertions(+), 2 deletions(-) diff --git a/backend/open_webui/utils/tool_approval.py b/backend/open_webui/utils/tool_approval.py index de43c77550..81fe750ec6 100644 --- a/backend/open_webui/utils/tool_approval.py +++ b/backend/open_webui/utils/tool_approval.py @@ -145,10 +145,14 @@ async def build_tool_approval_resume_payload(chat_id: str, message_id: str, chat chat_data = chat.chat or {} message_meta = assistant_message.get('meta') if isinstance(assistant_message.get('meta'), dict) else {} + chat_params = chat_data.get('params') if isinstance(chat_data.get('params'), dict) else {} params = { - **(chat_data.get('params') or {}), + **chat_params, **(message_meta.get('params') if isinstance(message_meta.get('params'), dict) else {}), } + current_approval_mode = chat_params.get('tool_approval_mode') + if current_approval_mode in {'ask', 'full'}: + params['tool_approval_mode'] = current_approval_mode if 'tool_approval_mode' not in params: params['tool_approval_mode'] = 'ask' diff --git a/src/lib/components/chat/Chat.svelte b/src/lib/components/chat/Chat.svelte index b0f345348d..dee368c489 100644 --- a/src/lib/components/chat/Chat.svelte +++ b/src/lib/components/chat/Chat.svelte @@ -425,7 +425,7 @@ ? 'ask' : 'full'; - const handleToolApprovalModeChange = async (mode) => { + const handleToolApprovalModeChange = async (mode: string) => { const tool_approval_mode = mode === 'ask' ? 'ask' : 'full'; params = { ...params, @@ -442,6 +442,54 @@ await updateUserSettings(localStorage.token, { ui: $settings }).catch((err) => { console.error('[tool permissions settings]', err); }); + + if ($chatId && !$temporaryChatEnabled && !isTemporaryChatId($chatId)) { + const res = await updateChatById(localStorage.token, $chatId, { params }).catch((err) => { + console.error('[tool permissions chat]', err); + return null; + }); + if (res) chat = res; + } + + if (tool_approval_mode === 'full') { + const messages = [...Object.values(history?.messages ?? {})].reverse() as any[]; + for (const message of messages) { + const output = (Array.isArray(message?.output) ? message.output : []) as any[]; + const resultCallIds = new Set( + output + .filter((item: any) => item?.type === 'function_call_output' && item?.call_id) + .map((item: any) => item.call_id) + ); + const pendingCall = output.find((item: any) => { + const callId = item?.call_id ?? item?.id; + return ( + item?.type === 'function_call' && + item?.name !== 'ask_user' && + (item?.status === 'pending' || item?.status === 'requires_approval') && + callId && + !resultCallIds.has(callId) + ); + }); + const callId = pendingCall?.call_id ?? pendingCall?.id; + if (!message?.id || !callId) { + continue; + } + + const res = await resolveChatMessageToolCall( + localStorage.token, + $chatId, + message.id, + callId, + 'approve' + ).catch(async (error) => { + toast.error(`${error}`); + await loadChat(); + return null; + }); + if (res) onToolCallResolved(res); + break; + } + } }; const parseToolArguments = (args) => {