From 9b9bea514dd5bfd0627d75e267c97caaaabc60a4 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Sun, 8 Nov 2026 19:06:43 +0900 Subject: [PATCH] refac --- backend/open_webui/config.py | 27 ++++------- backend/open_webui/main.py | 6 ++- backend/open_webui/models/chats.py | 8 +--- backend/open_webui/models/notifications.py | 4 +- backend/open_webui/routers/auths.py | 1 + backend/open_webui/routers/channels.py | 7 ++- backend/open_webui/routers/chats.py | 45 +++---------------- backend/open_webui/routers/terminals.py | 8 +++- backend/open_webui/routers/tether.py | 5 ++- backend/open_webui/utils/tether.py | 39 +++++++++++----- backend/open_webui/utils/tool_permissions.py | 15 +++---- backend/open_webui/utils/tools.py | 23 +++++++--- .../admin/Settings/Interface.svelte | 12 ----- 13 files changed, 91 insertions(+), 109 deletions(-) diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 83aaf4b2eb..6df4917a01 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -2263,20 +2263,14 @@ ENABLE_TOOL_PERMISSIONS = os.getenv('ENABLE_TOOL_PERMISSIONS', 'False').lower() ENABLE_TOOL_CALL_LABELS = os.getenv('ENABLE_TOOL_CALL_LABELS', 'False').lower() == 'true' ENABLE_TOOL_PERMISSIONS_AUTO = os.getenv('ENABLE_TOOL_PERMISSIONS_AUTO', 'False').lower() == 'true' TOOL_PERMISSIONS_AUTO_ENGINE = os.getenv('TOOL_PERMISSIONS_AUTO_ENGINE', '') -# None distinguishes an unset prompt from an explicit reset to the default policy. -TOOL_PERMISSIONS_AUTO_PROMPT = os.getenv('TOOL_PERMISSIONS_AUTO_PROMPT') -TOOL_PERMISSIONS_AUTO_DECISIONS_API_BASE_URL = os.getenv('TOOL_PERMISSIONS_AUTO_DECISIONS_API_BASE_URL') -TOOL_PERMISSIONS_AUTO_DECISIONS_API_KEY = os.getenv('TOOL_PERMISSIONS_AUTO_DECISIONS_API_KEY') -TOOL_PERMISSIONS_AUTO_DECISIONS_MODEL = os.getenv('TOOL_PERMISSIONS_AUTO_DECISIONS_MODEL') -TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD = os.getenv('TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD') -if TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD is not None: - TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD = float(TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD) -# Deprecated environment defaults, used only when their Auto replacements are unset. -TOOL_PERMISSIONS_DECISIONS_API_BASE_URL = os.getenv('TOOL_PERMISSIONS_DECISIONS_API_BASE_URL', 'https://api.openai.com/v1') -TOOL_PERMISSIONS_DECISIONS_API_KEY = os.getenv('TOOL_PERMISSIONS_DECISIONS_API_KEY', '') -TOOL_PERMISSIONS_DECISIONS_MODEL = os.getenv('TOOL_PERMISSIONS_DECISIONS_MODEL', 'gpt-6-luna') -TOOL_PERMISSIONS_DECISIONS_THRESHOLD = float(os.getenv('TOOL_PERMISSIONS_DECISIONS_THRESHOLD', '0.5')) -TOOL_PERMISSIONS_DECISIONS_PROMPT = os.getenv('TOOL_PERMISSIONS_DECISIONS_PROMPT', '') +TOOL_PERMISSIONS_AUTO_PROMPT = os.getenv('TOOL_PERMISSIONS_AUTO_PROMPT', '') +TOOL_PERMISSIONS_AUTO_DECISIONS_API_BASE_URL = os.getenv( + 'TOOL_PERMISSIONS_AUTO_DECISIONS_API_BASE_URL', 'https://api.openai.com/v1' +) +TOOL_PERMISSIONS_AUTO_DECISIONS_API_KEY = os.getenv('TOOL_PERMISSIONS_AUTO_DECISIONS_API_KEY', '') +TOOL_PERMISSIONS_AUTO_DECISIONS_MODEL = os.getenv('TOOL_PERMISSIONS_AUTO_DECISIONS_MODEL', 'gpt-6-luna') +TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD = float(os.getenv('TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD', '0.5')) + CONTEXT_COMPACTION_TOKEN_THRESHOLD = int(os.getenv('CONTEXT_COMPACTION_TOKEN_THRESHOLD', '80000')) @@ -3318,11 +3312,6 @@ DEFAULT_CONFIG = { 'chat.tool_permissions.auto.decisions.api_key': TOOL_PERMISSIONS_AUTO_DECISIONS_API_KEY, 'chat.tool_permissions.auto.decisions.model': TOOL_PERMISSIONS_AUTO_DECISIONS_MODEL, 'chat.tool_permissions.auto.decisions.threshold': TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD, - 'chat.tool_permissions.decisions.api_base_url': TOOL_PERMISSIONS_DECISIONS_API_BASE_URL, - 'chat.tool_permissions.decisions.api_key': TOOL_PERMISSIONS_DECISIONS_API_KEY, - 'chat.tool_permissions.decisions.model': TOOL_PERMISSIONS_DECISIONS_MODEL, - 'chat.tool_permissions.decisions.threshold': TOOL_PERMISSIONS_DECISIONS_THRESHOLD, - 'chat.tool_permissions.decisions.prompt': TOOL_PERMISSIONS_DECISIONS_PROMPT, 'chat.tool_search.enable': ENABLE_TOOL_SEARCH, 'chat.tool_search.engine': TOOL_SEARCH_ENGINE, 'chat.tool_search.decisions.api_base_url': TOOL_SEARCH_DECISIONS_API_BASE_URL, diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index b080af7964..52842994f7 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -1134,7 +1134,11 @@ async def chat_completion( if len(parts) != 4: raise HTTPException(400, 'Invalid agent model') candidates = await get_agent_models( - request, user, form_data.get('terminal_id'), form_data.get('chat_id'), provider=parts[2], + request, + user, + form_data.get('terminal_id'), + form_data.get('chat_id'), + provider=parts[2], cwd=requested_directory, ) agent_model = next((item for item in candidates if item['id'] == model_id), None) diff --git a/backend/open_webui/models/chats.py b/backend/open_webui/models/chats.py index 6e5ad30201..a11b541130 100644 --- a/backend/open_webui/models/chats.py +++ b/backend/open_webui/models/chats.py @@ -2850,9 +2850,7 @@ class ChatTable: await session.execute(delete(ChatMessage).filter_by(chat_id=id)) recipients = await delete_resource_comments('chat', select(Chat.id).filter_by(id=id), db=session) await session.execute( - delete(ChatViewState).where( - ChatViewState.chat_id.in_(select(Chat.id).filter_by(id=id)) - ) + delete(ChatViewState).where(ChatViewState.chat_id.in_(select(Chat.id).filter_by(id=id))) ) await session.execute(delete(Chat).filter_by(id=id)) await session.commit() @@ -2901,9 +2899,7 @@ class ChatTable: 'chat', select(Chat.id).filter_by(user_id=user_id), db=session ) await session.execute( - delete(ChatViewState).where( - ChatViewState.chat_id.in_(select(Chat.id).filter_by(user_id=user_id)) - ) + delete(ChatViewState).where(ChatViewState.chat_id.in_(select(Chat.id).filter_by(user_id=user_id))) ) await session.execute(delete(Chat).filter_by(user_id=user_id)) await session.commit() diff --git a/backend/open_webui/models/notifications.py b/backend/open_webui/models/notifications.py index f81d985756..eb7098024d 100644 --- a/backend/open_webui/models/notifications.py +++ b/backend/open_webui/models/notifications.py @@ -157,7 +157,9 @@ async def delete_notifications(*, resource_type=None, resource_ids=None, object_ return set(recipients) -async def update_notifications_read_at_by_resource_id(*, user_id: str, resource_type: str, resource_id: str, db) -> bool: +async def update_notifications_read_at_by_resource_id( + *, user_id: str, resource_type: str, resource_id: str, db +) -> bool: now = time.time_ns() result = await db.execute( update(Notification) diff --git a/backend/open_webui/routers/auths.py b/backend/open_webui/routers/auths.py index 9b8a68b85f..f0fe5991a5 100644 --- a/backend/open_webui/routers/auths.py +++ b/backend/open_webui/routers/auths.py @@ -924,6 +924,7 @@ async def signout(request: Request, response: Response, db: AsyncSession = Depen actor = await Users.get_user_by_id(data['id'], db=db) if data and data.get('typ', 'session') == 'session' and data.get('sid') and data.get('id'): from open_webui.models.auth_sessions import AuthSessions + await AuthSessions.revoke(data['sid'], data['id']) await invalidate_token(request, token) await publish_event( diff --git a/backend/open_webui/routers/channels.py b/backend/open_webui/routers/channels.py index acd07b8ae1..ba1c2993c0 100644 --- a/backend/open_webui/routers/channels.py +++ b/backend/open_webui/routers/channels.py @@ -1121,8 +1121,11 @@ async def send_notification(request, channel, message, active_user_ids, db=None) try: await notify( - u.id, f'channel:{channel.id}:{message.id}', f'{channel.name} / Open WebUI', - message.content, '/channels/' + quote(channel.id, safe=''), + u.id, + f'channel:{channel.id}:{message.id}', + f'{channel.name} / Open WebUI', + message.content, + '/channels/' + quote(channel.id, safe=''), ) except Exception: log.exception('Tether channel notification failed') diff --git a/backend/open_webui/routers/chats.py b/backend/open_webui/routers/chats.py index 99b8956af5..17068dec4c 100644 --- a/backend/open_webui/routers/chats.py +++ b/backend/open_webui/routers/chats.py @@ -50,7 +50,7 @@ from open_webui.utils.misc import get_message_list from open_webui.utils.models import get_all_models from open_webui.utils.tool_permissions import DEFAULT_TOOL_PERMISSIONS_AUTO_PROMPT, get_tool_permissions_auto_config from open_webui.utils.tool_search import DEFAULT_TOOL_SEARCH_DECISIONS_PROMPT, validate_decisions_config -from pydantic import AliasChoices, BaseModel, Field, ValidationError, field_validator, model_validator +from pydantic import BaseModel, Field, ValidationError, field_validator, model_validator from sqlalchemy.ext.asyncio import AsyncSession log = logging.getLogger(__name__) @@ -237,33 +237,12 @@ class ChatConfigForm(BaseModel): ENABLE_TOOL_PERMISSIONS: bool = False ENABLE_TOOL_CALL_LABELS: bool = False ENABLE_TOOL_PERMISSIONS_AUTO: bool = False - TOOL_PERMISSIONS_AUTO_DECISIONS_API_BASE_URL: str = Field( - default='https://api.openai.com/v1', - validation_alias=AliasChoices( - 'TOOL_PERMISSIONS_AUTO_DECISIONS_API_BASE_URL', 'TOOL_PERMISSIONS_DECISIONS_API_BASE_URL' - ), - ) - TOOL_PERMISSIONS_AUTO_DECISIONS_API_KEY: str = Field( - default='', - validation_alias=AliasChoices('TOOL_PERMISSIONS_AUTO_DECISIONS_API_KEY', 'TOOL_PERMISSIONS_DECISIONS_API_KEY'), - ) - TOOL_PERMISSIONS_AUTO_DECISIONS_MODEL: str = Field( - default='gpt-6-luna', - validation_alias=AliasChoices('TOOL_PERMISSIONS_AUTO_DECISIONS_MODEL', 'TOOL_PERMISSIONS_DECISIONS_MODEL'), - ) - TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD: float = Field( - default=0.5, - validation_alias=AliasChoices( - 'TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD', 'TOOL_PERMISSIONS_DECISIONS_THRESHOLD' - ), - ge=0, - le=1, - allow_inf_nan=False, - ) TOOL_PERMISSIONS_AUTO_ENGINE: Literal['', 'decisions'] = '' - TOOL_PERMISSIONS_AUTO_PROMPT: str = Field( - default='', validation_alias=AliasChoices('TOOL_PERMISSIONS_AUTO_PROMPT', 'TOOL_PERMISSIONS_DECISIONS_PROMPT') - ) + TOOL_PERMISSIONS_AUTO_PROMPT: str = '' + TOOL_PERMISSIONS_AUTO_DECISIONS_API_BASE_URL: str = 'https://api.openai.com/v1' + TOOL_PERMISSIONS_AUTO_DECISIONS_API_KEY: str = '' + TOOL_PERMISSIONS_AUTO_DECISIONS_MODEL: str = 'gpt-6-luna' + TOOL_PERMISSIONS_AUTO_DECISIONS_THRESHOLD: float = Field(default=0.5, ge=0, le=1, allow_inf_nan=False) ENABLE_TOOL_SEARCH: bool = False TOOL_SEARCH_ENGINE: Literal['bm25', 'embeddings', 'decisions'] = 'bm25' TOOL_SEARCH_DECISIONS_API_BASE_URL: str = 'https://api.openai.com/v1' @@ -303,13 +282,6 @@ class ChatConfigForm(BaseModel): class ChatConfigResponse(ChatConfigForm): DEFAULT_TOOL_PERMISSIONS_AUTO_PROMPT: str = DEFAULT_TOOL_PERMISSIONS_AUTO_PROMPT - TOOL_PERMISSIONS_DECISIONS_API_BASE_URL: str = 'https://api.openai.com/v1' - TOOL_PERMISSIONS_DECISIONS_API_KEY: str = '' - TOOL_PERMISSIONS_DECISIONS_MODEL: str = 'gpt-6-luna' - TOOL_PERMISSIONS_DECISIONS_THRESHOLD: float = 0.5 - # Deprecated response aliases for older settings clients. - TOOL_PERMISSIONS_DECISIONS_PROMPT: str = '' - DEFAULT_TOOL_PERMISSIONS_DECISIONS_PROMPT: str = DEFAULT_TOOL_PERMISSIONS_AUTO_PROMPT DEFAULT_TOOL_SEARCH_DECISIONS_PROMPT: str = DEFAULT_TOOL_SEARCH_DECISIONS_PROMPT TOOL_SEARCH_EMBEDDING_MODEL: str = '' @@ -329,12 +301,9 @@ async def get_chat_config_values() -> dict: config['CONTEXT_COMPACTION_RETENTION_PERCENTAGE'] = 40 auto_config = await get_tool_permissions_auto_config() config['TOOL_PERMISSIONS_AUTO_PROMPT'] = auto_config['prompt'] - config['TOOL_PERMISSIONS_DECISIONS_PROMPT'] = auto_config['prompt'] for key in ('api_base_url', 'api_key', 'model', 'threshold'): config[f'TOOL_PERMISSIONS_AUTO_DECISIONS_{key.upper()}'] = auto_config[key] - config[f'TOOL_PERMISSIONS_DECISIONS_{key.upper()}'] = auto_config[key] config['DEFAULT_TOOL_PERMISSIONS_AUTO_PROMPT'] = DEFAULT_TOOL_PERMISSIONS_AUTO_PROMPT - config['DEFAULT_TOOL_PERMISSIONS_DECISIONS_PROMPT'] = DEFAULT_TOOL_PERMISSIONS_AUTO_PROMPT config['DEFAULT_TOOL_SEARCH_DECISIONS_PROMPT'] = DEFAULT_TOOL_SEARCH_DECISIONS_PROMPT config['TOOL_SEARCH_EMBEDDING_MODEL'] = values.get('rag.embedding_model') or '' return config @@ -958,7 +927,7 @@ async def set_chat_config(form_data: ChatConfigForm, user=Depends(get_admin_user for field in ChatConfigForm.model_fields: if ( field in {'TOOL_SEARCH_ENGINE', 'ENABLE_TOOL_PERMISSIONS_AUTO', 'ENABLE_TOOL_CALL_LABELS'} - or field.startswith(('TOOL_SEARCH_DECISIONS_', 'TOOL_PERMISSIONS_DECISIONS_', 'TOOL_PERMISSIONS_AUTO_')) + or field.startswith(('TOOL_SEARCH_DECISIONS_', 'TOOL_PERMISSIONS_AUTO_')) ) and (field not in form_data.model_fields_set): updates[field] = current.get(field, updates[field]) try: diff --git a/backend/open_webui/routers/terminals.py b/backend/open_webui/routers/terminals.py index 8365043ffb..c4a0a73f86 100644 --- a/backend/open_webui/routers/terminals.py +++ b/backend/open_webui/routers/terminals.py @@ -239,7 +239,9 @@ async def browser_ws(ws: WebSocket, server_id: str, sid: str, ticket: str, kind: headers['Authorization'] = data['relay']['authorization'] tasks = [] try: - async with get_terminal_client(base, user.id, cookies=data['relay'].get('cookies', {}), trust_env=True) as client: + async with get_terminal_client( + base, user.id, cookies=data['relay'].get('cookies', {}), trust_env=True + ) as client: async with client.ws_connect( url, headers=headers, @@ -398,7 +400,9 @@ async def proxy_terminal( if content_type: headers['Content-Type'] = content_type - session = get_terminal_client(base_url, user.id, + session = get_terminal_client( + base_url, + user.id, timeout=aiohttp.ClientTimeout(total=300, connect=10), trust_env=True, ) diff --git a/backend/open_webui/routers/tether.py b/backend/open_webui/routers/tether.py index 21989785bd..1a6e45696f 100644 --- a/backend/open_webui/routers/tether.py +++ b/backend/open_webui/routers/tether.py @@ -123,7 +123,10 @@ async def connect(ws: WebSocket): if hub.redis: replaced = await hub.redis.eval( "if redis.call('get', KEYS[1]) == ARGV[1] then redis.call('set', KEYS[1], ARGV[2], 'EX', 60); return 1 else return 0 end", - 1, key, record, updated_record, + 1, + key, + record, + updated_record, ) if not replaced: raise ValueError('Tether connection was replaced') diff --git a/backend/open_webui/utils/tether.py b/backend/open_webui/utils/tether.py index 4965e469a0..50ab9e92d8 100644 --- a/backend/open_webui/utils/tether.py +++ b/backend/open_webui/utils/tether.py @@ -87,9 +87,7 @@ class Stream: def set_timeout(self, timeout): self.read_timeout = timeout.sock_read if timeout.sock_read and timeout.sock_read > 0 else None if timeout.total and timeout.total > 0: - self.timeout_handle = asyncio.get_running_loop().call_later( - timeout.total, self.fail, 'Request timed out' - ) + self.timeout_handle = asyncio.get_running_loop().call_later(timeout.total, self.fail, 'Request timed out') async def send(self, operation, data=b'', **fields): while len(data) > self.credit and not self.closed: @@ -355,20 +353,39 @@ async def notify(user_id, notification_id, title, body, path): if not presences: return user = await Users.get_user_by_id(user_id) - if not user or user.role == 'pending' or not user.settings or not (user.settings.ui or {}).get('notificationEnabled', False): + if ( + not user + or user.role == 'pending' + or not user.settings + or not (user.settings.ui or {}).get('notificationEnabled', False) + ): return - payload = json.dumps({ - 'id': str(notification_id)[:200], 'user_id': user_id, - 'title': str(title)[:256], 'body': str(body)[:4096], 'path': path, - }).encode() + payload = json.dumps( + { + 'id': str(notification_id)[:200], + 'user_id': user_id, + 'title': str(title)[:256], + 'body': str(body)[:4096], + 'path': path, + } + ).encode() for presence in presences: row = await AuthSessions.get(presence['session']) if not row or row.user_id != user_id or row.refresh_token_id is None or row.expires_at <= time.time(): continue with suppress(Exception): - await asyncio.wait_for(hub.send(presence, { - 'type': 'notification', 'stream': str(uuid4()), 'sequence': 0, - }, payload), 10) + await asyncio.wait_for( + hub.send( + presence, + { + 'type': 'notification', + 'stream': str(uuid4()), + 'sequence': 0, + }, + payload, + ), + 10, + ) async def get_terminal_connections(user): diff --git a/backend/open_webui/utils/tool_permissions.py b/backend/open_webui/utils/tool_permissions.py index e6f91d6746..bf9cc169a0 100644 --- a/backend/open_webui/utils/tool_permissions.py +++ b/backend/open_webui/utils/tool_permissions.py @@ -28,16 +28,11 @@ async def get_tool_permissions_auto_config(): storage_keys = { key: f'chat.tool_permissions.auto.{"prompt" if key == "prompt" else "decisions." + key}' for key in keys } - values = await Config.get_many(*storage_keys.values(), *(f'chat.tool_permissions.decisions.{key}' for key in keys)) - settings = {} - for key, storage_key in storage_keys.items(): - value = values.get(storage_key) - if value is None: - value = Config.default_value(storage_key) - if value is None: - value = values.get(f'chat.tool_permissions.decisions.{key}', '' if key == 'prompt' else None) - settings[key] = value - return settings + values = await Config.get_many(*storage_keys.values()) + return { + key: values[storage_key] if values.get(storage_key) is not None else Config.default_value(storage_key) + for key, storage_key in storage_keys.items() + } def set_tool_approval_prompt(messages, policy=None): diff --git a/backend/open_webui/utils/tools.py b/backend/open_webui/utils/tools.py index c5aeb7dd87..e42f673c69 100644 --- a/backend/open_webui/utils/tools.py +++ b/backend/open_webui/utils/tools.py @@ -1378,7 +1378,9 @@ async def get_terminal_cwd( """Fetch the current working directory from a terminal server.""" try: cwd_url = f'{base_url.rstrip("/")}/files/cwd' - async with get_terminal_client(base_url, headers.get('X-User-Id'), + async with get_terminal_client( + base_url, + headers.get('X-User-Id'), timeout=aiohttp.ClientTimeout(total=5), trust_env=True, ) as session: @@ -1406,7 +1408,9 @@ async def get_terminal_system_prompt( """ base = base_url.rstrip('/') try: - async with get_terminal_client(base_url, headers.get('X-User-Id'), + async with get_terminal_client( + base_url, + headers.get('X-User-Id'), timeout=aiohttp.ClientTimeout(total=3), trust_env=True, ) as session: @@ -1563,8 +1567,12 @@ async def get_terminal_tools( if connection.get('owner_id') == user.id: url = connection['url'] openapi = await get_tool_server_data(url + '/openapi.json', {'X-User-Id': user.id}) - server_data = {'id': terminal_id, 'url': url, 'openapi': openapi, - 'specs': convert_openapi_to_tool_payload(openapi)} + server_data = { + 'id': terminal_id, + 'url': url, + 'openapi': openapi, + 'specs': convert_openapi_to_tool_payload(openapi), + } else: terminal_servers = await get_terminal_servers(request) server_data = next((server for server in terminal_servers if server.get('id') == terminal_id), None) @@ -1918,8 +1926,11 @@ async def execute_tool_server( else: body_params = params - async with get_terminal_client(url, (headers or {}).get('X-User-Id'), - trust_env=True, timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER) + async with get_terminal_client( + url, + (headers or {}).get('X-User-Id'), + trust_env=True, + timeout=aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER), ) as session: request_method = getattr(session, http_method.lower()) diff --git a/src/lib/components/admin/Settings/Interface.svelte b/src/lib/components/admin/Settings/Interface.svelte index dde54ee454..921c6ff616 100644 --- a/src/lib/components/admin/Settings/Interface.svelte +++ b/src/lib/components/admin/Settings/Interface.svelte @@ -82,23 +82,11 @@ const { DEFAULT_TOOL_SEARCH_DECISIONS_PROMPT = '', DEFAULT_TOOL_PERMISSIONS_AUTO_PROMPT = '', - DEFAULT_TOOL_PERMISSIONS_DECISIONS_PROMPT: _legacyDefaultPrompt, - TOOL_PERMISSIONS_DECISIONS_API_BASE_URL: _legacyAPI_BASE_URL, - TOOL_PERMISSIONS_DECISIONS_API_KEY: _legacyAPI_KEY, - TOOL_PERMISSIONS_DECISIONS_MODEL: _legacyMODEL, - TOOL_PERMISSIONS_DECISIONS_THRESHOLD: _legacyTHRESHOLD, - TOOL_PERMISSIONS_DECISIONS_PROMPT: _legacyPrompt, TOOL_SEARCH_EMBEDDING_MODEL = '', ...settings } = chatConfig as typeof chatConfig & { DEFAULT_TOOL_SEARCH_DECISIONS_PROMPT?: string; DEFAULT_TOOL_PERMISSIONS_AUTO_PROMPT?: string; - DEFAULT_TOOL_PERMISSIONS_DECISIONS_PROMPT?: string; - TOOL_PERMISSIONS_DECISIONS_API_BASE_URL?: string; - TOOL_PERMISSIONS_DECISIONS_API_KEY?: string; - TOOL_PERMISSIONS_DECISIONS_MODEL?: string; - TOOL_PERMISSIONS_DECISIONS_THRESHOLD?: number; - TOOL_PERMISSIONS_DECISIONS_PROMPT?: string; TOOL_SEARCH_EMBEDDING_MODEL?: string; }; defaultDecisionsPrompt = DEFAULT_TOOL_SEARCH_DECISIONS_PROMPT;