diff --git a/backend/open_webui/config.py b/backend/open_webui/config.py index 661db353af..dbf9fad19b 100644 --- a/backend/open_webui/config.py +++ b/backend/open_webui/config.py @@ -172,7 +172,6 @@ def get_config_value(config_path: str): PERSISTENT_CONFIG_REGISTRY = [] - def save_config(config): """Sync save — used ONLY at startup/import time.""" global CONFIG_DATA @@ -2666,8 +2665,12 @@ ONEDRIVE_CLIENT_ID = os.environ.get('ONEDRIVE_CLIENT_ID', '') ONEDRIVE_CLIENT_ID_PERSONAL = os.environ.get('ONEDRIVE_CLIENT_ID_PERSONAL', ONEDRIVE_CLIENT_ID) ONEDRIVE_CLIENT_ID_BUSINESS = os.environ.get('ONEDRIVE_CLIENT_ID_BUSINESS', ONEDRIVE_CLIENT_ID) -ENABLE_ONEDRIVE_PERSONAL = os.environ.get('ENABLE_ONEDRIVE_PERSONAL', 'True').lower() == 'true' and bool(ONEDRIVE_CLIENT_ID_PERSONAL) -ENABLE_ONEDRIVE_BUSINESS = os.environ.get('ENABLE_ONEDRIVE_BUSINESS', 'True').lower() == 'true' and bool(ONEDRIVE_CLIENT_ID_BUSINESS) +ENABLE_ONEDRIVE_PERSONAL = os.environ.get('ENABLE_ONEDRIVE_PERSONAL', 'True').lower() == 'true' and bool( + ONEDRIVE_CLIENT_ID_PERSONAL +) +ENABLE_ONEDRIVE_BUSINESS = os.environ.get('ENABLE_ONEDRIVE_BUSINESS', 'True').lower() == 'true' and bool( + ONEDRIVE_CLIENT_ID_BUSINESS +) ONEDRIVE_SHAREPOINT_URL = PersistentConfig( 'ONEDRIVE_SHAREPOINT_URL', diff --git a/backend/open_webui/env.py b/backend/open_webui/env.py index d6cf24a83c..8a9b3af365 100644 --- a/backend/open_webui/env.py +++ b/backend/open_webui/env.py @@ -258,9 +258,7 @@ ENABLE_EASTER_EGGS = os.environ.get('ENABLE_EASTER_EGGS', 'True').lower() == 'tr # 302 redirect to the original origin. Set to False to suppress the # redirect (prevents client-side IP/UA/Referer leaks to attacker- # controlled origins) and fall through to the default image instead. -ENABLE_PROFILE_IMAGE_URL_FORWARDING = os.environ.get( - 'ENABLE_PROFILE_IMAGE_URL_FORWARDING', 'True' -).lower() == 'true' +ENABLE_PROFILE_IMAGE_URL_FORWARDING = os.environ.get('ENABLE_PROFILE_IMAGE_URL_FORWARDING', 'True').lower() == 'true' #################################### # WEBUI_BUILD_HASH diff --git a/backend/open_webui/internal/db.py b/backend/open_webui/internal/db.py index 1bb9db5bb4..9a6576fd7c 100644 --- a/backend/open_webui/internal/db.py +++ b/backend/open_webui/internal/db.py @@ -339,6 +339,7 @@ ASYNC_SQLALCHEMY_DATABASE_URL = _make_async_url(SQLALCHEMY_DATABASE_URL) # to cover every entry point (workers, reload, direct invocations). if sys.platform == 'win32' and _is_postgres_url(DATABASE_URL): import asyncio + asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy()) if 'sqlite' in ASYNC_SQLALCHEMY_DATABASE_URL: diff --git a/backend/open_webui/main.py b/backend/open_webui/main.py index 9bdc804b45..52e59d26e0 100644 --- a/backend/open_webui/main.py +++ b/backend/open_webui/main.py @@ -1565,7 +1565,7 @@ async def unload_model(request: Request, form_data: ModelUnloadForm, user=Depend prefix_id = api_config.get('prefix_id', None) actual_model = model_id if prefix_id and actual_model.startswith(f'{prefix_id}.'): - actual_model = actual_model[len(f'{prefix_id}.'):] + actual_model = actual_model[len(f'{prefix_id}.') :] payload = json.dumps({'model': actual_model, 'keep_alive': 0, 'prompt': ''}) @@ -1574,7 +1574,7 @@ async def unload_model(request: Request, form_data: ModelUnloadForm, user=Depend async with aiohttp.ClientSession(timeout=timeout, trust_env=True) as session: headers = { 'Content-Type': 'application/json', - **({"Authorization": f"Bearer {key}"} if key else {}), + **({'Authorization': f'Bearer {key}'} if key else {}), } async with session.post( f'{url}/api/generate', @@ -1602,7 +1602,9 @@ async def unload_model(request: Request, form_data: ModelUnloadForm, user=Depend api_config = request.app.state.config.OPENAI_API_CONFIGS.get(str(idx), {}) provider = api_config.get('provider', '') base_url = request.app.state.config.OPENAI_API_BASE_URLS[idx] - key = request.app.state.config.OPENAI_API_KEYS[idx] if idx < len(request.app.state.config.OPENAI_API_KEYS) else '' + key = ( + request.app.state.config.OPENAI_API_KEYS[idx] if idx < len(request.app.state.config.OPENAI_API_KEYS) else '' + ) if provider == 'llama.cpp': root_url = base_url.rstrip('/').removesuffix('/v1') @@ -1611,7 +1613,7 @@ async def unload_model(request: Request, form_data: ModelUnloadForm, user=Depend async with aiohttp.ClientSession(timeout=timeout, trust_env=True) as session: headers = { 'Content-Type': 'application/json', - **({"Authorization": f"Bearer {key}"} if key else {}), + **({'Authorization': f'Bearer {key}'} if key else {}), } async with session.post( f'{root_url}/models/unload', @@ -2076,9 +2078,7 @@ async def chat_completion( event_emitter = await get_event_emitter(metadata, update_db=False) if event_emitter: try: - await asyncio.shield( - event_emitter({'type': 'chat:active', 'data': {'active': False}}) - ) + await asyncio.shield(event_emitter({'type': 'chat:active', 'data': {'active': False}})) except asyncio.CancelledError: pass except Exception: diff --git a/backend/open_webui/migrations/versions/4de81c2a3af1_add_pinned_note_table.py b/backend/open_webui/migrations/versions/4de81c2a3af1_add_pinned_note_table.py index b2bc805773..858c9b1541 100644 --- a/backend/open_webui/migrations/versions/4de81c2a3af1_add_pinned_note_table.py +++ b/backend/open_webui/migrations/versions/4de81c2a3af1_add_pinned_note_table.py @@ -5,6 +5,7 @@ Revises: 56359461a091 Create Date: 2026-05-09 04:29:27.651341 """ + from typing import Sequence, Union from alembic import op @@ -24,6 +25,7 @@ import time from sqlalchemy import select, update, insert from sqlalchemy.sql import table, column + def upgrade() -> None: op.create_table( 'pinned_note', @@ -32,66 +34,47 @@ def upgrade() -> None: sa.Column('note_id', sa.Text(), sa.ForeignKey('note.id', ondelete='CASCADE'), nullable=False), sa.Column('created_at', sa.BigInteger(), nullable=False), sa.PrimaryKeyConstraint('id'), - sa.UniqueConstraint('user_id', 'note_id', name='uq_pinned_note') + sa.UniqueConstraint('user_id', 'note_id', name='uq_pinned_note'), ) - + conn = op.get_bind() - - note_table = table('note', - column('id', sa.Text), - column('user_id', sa.Text), - column('is_pinned', sa.Boolean) - ) - - pinned_note_table = table('pinned_note', + + note_table = table('note', column('id', sa.Text), column('user_id', sa.Text), column('is_pinned', sa.Boolean)) + + pinned_note_table = table( + 'pinned_note', column('id', sa.Text), column('user_id', sa.Text), column('note_id', sa.Text), - column('created_at', sa.BigInteger) + column('created_at', sa.BigInteger), ) - - notes = conn.execute( - select(note_table.c.id, note_table.c.user_id).where(note_table.c.is_pinned == True) - ).fetchall() - + + notes = conn.execute(select(note_table.c.id, note_table.c.user_id).where(note_table.c.is_pinned == True)).fetchall() + if notes: now = int(time.time_ns()) conn.execute( insert(pinned_note_table), - [ - { - "id": str(uuid.uuid4()), - "user_id": note[1], - "note_id": note[0], - "created_at": now - } - for note in notes - ] + [{'id': str(uuid.uuid4()), 'user_id': note[1], 'note_id': note[0], 'created_at': now} for note in notes], ) with op.batch_alter_table('note', schema=None) as batch_op: batch_op.drop_column('is_pinned') + def downgrade() -> None: with op.batch_alter_table('note', schema=None) as batch_op: batch_op.add_column(sa.Column('is_pinned', sa.Boolean(), nullable=True)) - + conn = op.get_bind() - - note_table = table('note', - column('id', sa.Text), - column('is_pinned', sa.Boolean) - ) - - pinned_note_table = table('pinned_note', - column('note_id', sa.Text) - ) - + + note_table = table('note', column('id', sa.Text), column('is_pinned', sa.Boolean)) + + pinned_note_table = table('pinned_note', column('note_id', sa.Text)) + notes = conn.execute(select(pinned_note_table.c.note_id)).fetchall() - + for note in notes: - conn.execute( - update(note_table).where(note_table.c.id == note[0]).values(is_pinned=True) - ) - + conn.execute(update(note_table).where(note_table.c.id == note[0]).values(is_pinned=True)) + op.drop_table('pinned_note') diff --git a/backend/open_webui/models/chat_messages.py b/backend/open_webui/models/chat_messages.py index 44349c1584..a7d875c9dc 100644 --- a/backend/open_webui/models/chat_messages.py +++ b/backend/open_webui/models/chat_messages.py @@ -260,9 +260,7 @@ class ChatMessageTable: embedded JSON blob for legacy chats). """ async with get_async_db_context(db) as db: - result = await db.execute( - select(ChatMessage).filter_by(chat_id=chat_id) - ) + result = await db.execute(select(ChatMessage).filter_by(chat_id=chat_id)) rows = result.scalars().all() if not rows: diff --git a/backend/open_webui/models/notes.py b/backend/open_webui/models/notes.py index 33928bf970..a665004a95 100644 --- a/backend/open_webui/models/notes.py +++ b/backend/open_webui/models/notes.py @@ -323,29 +323,28 @@ class NoteTable: await db.commit() return await self._to_note_model(note, db=db) if note else None - async def toggle_note_pinned_by_id(self, id: str, user_id: str, db: Optional[AsyncSession] = None) -> Optional[NoteModel]: + async def toggle_note_pinned_by_id( + self, id: str, user_id: str, db: Optional[AsyncSession] = None + ) -> Optional[NoteModel]: try: async with get_async_db_context(db) as db: result = await db.execute(select(Note).filter(Note.id == id)) note = result.scalars().first() if not note: return None - + # Check if already pinned pin_result = await db.execute(select(PinnedNote).filter_by(user_id=user_id, note_id=id)) pinned_note = pin_result.scalars().first() - + if pinned_note: await db.execute(delete(PinnedNote).filter_by(user_id=user_id, note_id=id)) else: new_pin = PinnedNote( - id=str(uuid.uuid4()), - user_id=user_id, - note_id=id, - created_at=int(time.time_ns()) + id=str(uuid.uuid4()), user_id=user_id, note_id=id, created_at=int(time.time_ns()) ) db.add(new_pin) - + await db.commit() return await self._to_note_model(note, db=db) except Exception: @@ -361,7 +360,12 @@ class NoteTable: user_groups = await Groups.get_groups_by_member_id(user_id, db=db) user_group_ids = [group.id for group in user_groups] - stmt = select(Note).join(PinnedNote, PinnedNote.note_id == Note.id).filter(PinnedNote.user_id == user_id).order_by(PinnedNote.created_at.desc()) + stmt = ( + select(Note) + .join(PinnedNote, PinnedNote.note_id == Note.id) + .filter(PinnedNote.user_id == user_id) + .order_by(PinnedNote.created_at.desc()) + ) stmt = self._has_permission(db, stmt, {'user_id': user_id, 'group_ids': user_group_ids}, permission) result = await db.execute(stmt) diff --git a/backend/open_webui/models/prompts.py b/backend/open_webui/models/prompts.py index 70c05094b8..5a3e35d23d 100644 --- a/backend/open_webui/models/prompts.py +++ b/backend/open_webui/models/prompts.py @@ -235,11 +235,7 @@ class PromptsTable: user_groups = await Groups.get_groups_by_member_id(user_id, db=db) user_group_ids = [group.id for group in user_groups] - query = ( - select(Prompt) - .filter(Prompt.is_active == True) - .order_by(Prompt.updated_at.desc()) - ) + query = select(Prompt).filter(Prompt.is_active == True).order_by(Prompt.updated_at.desc()) query = AccessGrants.has_permission_filter( db=db, query=query, diff --git a/backend/open_webui/retrieval/loaders/main.py b/backend/open_webui/retrieval/loaders/main.py index d507ed8c69..2daa641bf2 100644 --- a/backend/open_webui/retrieval/loaders/main.py +++ b/backend/open_webui/retrieval/loaders/main.py @@ -135,7 +135,6 @@ class PptxLoader: ] - class TikaLoader: def __init__(self, url, file_path, mime_type=None, extract_images=None): self.url = url diff --git a/backend/open_webui/retrieval/web/duckduckgo.py b/backend/open_webui/retrieval/web/duckduckgo.py index a98f43625c..5b2f076227 100644 --- a/backend/open_webui/retrieval/web/duckduckgo.py +++ b/backend/open_webui/retrieval/web/duckduckgo.py @@ -37,9 +37,9 @@ def search_duckduckgo( # Use the ddgs.text() method to perform the search try: - kwargs = {"safesearch": "moderate", "max_results": count} - if backend and backend != "auto": - kwargs["backend"] = backend + kwargs = {'safesearch': 'moderate', 'max_results': count} + if backend and backend != 'auto': + kwargs['backend'] = backend results = ddgs.text(query, **kwargs) search_results = results if results is not None else [] except RatelimitException as e: diff --git a/backend/open_webui/routers/audio.py b/backend/open_webui/routers/audio.py index 5cf5de5aee..6366f0e72b 100644 --- a/backend/open_webui/routers/audio.py +++ b/backend/open_webui/routers/audio.py @@ -147,8 +147,7 @@ def transcode_audio_to_mp3(audio_data: bytes, content_type_header: str, output_p if BYPASS_PYDUB_PREPROCESSING: log.warning( - f'TTS returned {mime_type} but BYPASS_PYDUB_PREPROCESSING is set; ' - f'writing raw audio without transcoding' + f'TTS returned {mime_type} but BYPASS_PYDUB_PREPROCESSING is set; writing raw audio without transcoding' ) return False @@ -1190,7 +1189,7 @@ def transcribe(request: Request, file_path: str, metadata: Optional[dict] = None results = [] try: - if getattr(request.app.state.config, "STT_ENGINE", "") == "": + if getattr(request.app.state.config, 'STT_ENGINE', '') == '': max_workers = 1 else: max_workers = None diff --git a/backend/open_webui/routers/configs.py b/backend/open_webui/routers/configs.py index 901d0320e7..1d55dba75e 100644 --- a/backend/open_webui/routers/configs.py +++ b/backend/open_webui/routers/configs.py @@ -374,7 +374,11 @@ async def verify_tool_servers_config(request: Request, form_data: ToolServerConn try: if form_data.type == 'mcp': if form_data.auth_type in ('oauth_2.1', 'oauth_2.1_static'): - oauth_server_url = form_data.info.get('oauth_server_url') if form_data.info and form_data.info.get('oauth_server_url') else form_data.url + oauth_server_url = ( + form_data.info.get('oauth_server_url') + if form_data.info and form_data.info.get('oauth_server_url') + else form_data.url + ) discovery_urls = await get_discovery_urls(oauth_server_url) for discovery_url in discovery_urls: log.debug(f'Trying to fetch OAuth 2.1 discovery document from {discovery_url}') diff --git a/backend/open_webui/routers/notes.py b/backend/open_webui/routers/notes.py index 7149a67b2f..9a23a104c9 100644 --- a/backend/open_webui/routers/notes.py +++ b/backend/open_webui/routers/notes.py @@ -347,7 +347,7 @@ async def update_note_by_id( note = await Notes.update_note_by_id(id, form_data, db=db) pinned_note_ids = await Notes.get_pinned_note_ids(user.id, db=db) note.is_pinned = note.id in pinned_note_ids - + await sio.emit( 'note-events', note.model_dump(), diff --git a/backend/open_webui/routers/openai.py b/backend/open_webui/routers/openai.py index 3105653eb1..3cf3cd9f4a 100644 --- a/backend/open_webui/routers/openai.py +++ b/backend/open_webui/routers/openai.py @@ -517,9 +517,7 @@ async def get_openai_loaded_models(request: Request, models: dict, api_base_urls key = api_keys[idx] if idx < len(api_keys) else None slots = await send_get_request(url=f'{root_url}/slots', key=key) loaded_model_ids = ( - {s.get('model') for s in slots if s.get('model')} - if isinstance(slots, list) - else set() + {s.get('model') for s in slots if s.get('model')} if isinstance(slots, list) else set() ) for model_id, model in models.items(): if model.get('urlIdx') == idx: diff --git a/backend/open_webui/tools/builtin.py b/backend/open_webui/tools/builtin.py index cce818fec4..ef408ab8af 100644 --- a/backend/open_webui/tools/builtin.py +++ b/backend/open_webui/tools/builtin.py @@ -3140,8 +3140,6 @@ async def create_calendar_event( return json.dumps({'error': str(e)}) - - async def update_calendar_event( event_id: str, title: Optional[str] = None, diff --git a/backend/open_webui/utils/headers.py b/backend/open_webui/utils/headers.py index fabd13d7d5..f5ad41bcd2 100644 --- a/backend/open_webui/utils/headers.py +++ b/backend/open_webui/utils/headers.py @@ -17,6 +17,7 @@ def include_user_info_headers(headers, user): FORWARD_USER_INFO_HEADER_USER_ROLE: user.role, } + def get_custom_headers(custom_headers: dict, user=None, metadata: dict = None) -> dict: if not custom_headers or not isinstance(custom_headers, dict): return {} @@ -28,7 +29,7 @@ def get_custom_headers(custom_headers: dict, user=None, metadata: dict = None) - '{{USER_ID}}': (user.id if user else '') or '', '{{USER_NAME}}': (user.name if user else '') or '', } - + parsed_headers = {} for key, value in custom_headers.items(): if not isinstance(value, str): @@ -36,5 +37,5 @@ def get_custom_headers(custom_headers: dict, user=None, metadata: dict = None) - for token, val in template_vars.items(): value = value.replace(token, val) parsed_headers[key] = value - + return parsed_headers diff --git a/backend/open_webui/utils/middleware.py b/backend/open_webui/utils/middleware.py index 7d67e60ade..361f2158cd 100644 --- a/backend/open_webui/utils/middleware.py +++ b/backend/open_webui/utils/middleware.py @@ -2459,7 +2459,7 @@ async def process_chat_payload(request, form_data, user, metadata, model): extra_params['__features__'] = features if features: if 'voice' in features and features['voice']: - if getattr(request.app.state.config, "ENABLE_VOICE_MODE_PROMPT", True): + if getattr(request.app.state.config, 'ENABLE_VOICE_MODE_PROMPT', True): if request.app.state.config.VOICE_MODE_PROMPT_TEMPLATE: template = request.app.state.config.VOICE_MODE_PROMPT_TEMPLATE else: @@ -4085,9 +4085,9 @@ async def streaming_chat_response_handler(response, ctx): current_response_tool_call['function']['name'] = delta_name if delta_arguments: - current_response_tool_call['function'][ - 'arguments' - ] += delta_arguments + current_response_tool_call['function']['arguments'] += ( + delta_arguments + ) # Emit pending tool calls in real-time if response_tool_calls: diff --git a/backend/open_webui/utils/plugin.py b/backend/open_webui/utils/plugin.py index a6f4388d7f..1862e17660 100644 --- a/backend/open_webui/utils/plugin.py +++ b/backend/open_webui/utils/plugin.py @@ -400,7 +400,7 @@ def install_frontmatter_requirements(requirements: str): try: req_list = [req.strip() for req in requirements.split(',')] new_reqs = [req for req in req_list if req and req not in _installed_requirements] - + if not new_reqs: return diff --git a/package-lock.json b/package-lock.json index 35554ac1d4..bd0b78c051 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "open-webui", - "version": "0.9.2", + "version": "0.9.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "open-webui", - "version": "0.9.2", + "version": "0.9.3", "dependencies": { "@azure/msal-browser": "^4.5.0", "@codemirror/lang-javascript": "^6.2.2", @@ -3582,9 +3582,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.58.0", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.58.0.tgz", - "integrity": "sha512-kT9GCN8yJTkCK1W+Gi/bvGooWAM7y7WXP+yd+rf6QOIjyoK1ERPrMwSufXJUNu2pMWIqruhFvmz+LbOqsEmKmA==", + "version": "2.59.1", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.59.1.tgz", + "integrity": "sha512-d8OON70AphLdDesuTIl//M2O6fRTIicX8aYv8vhCiYEhTTI2OboKqey0Hu1A4VFhqwgqtq0vKDmPFGkw8kKmgw==", "license": "MIT", "dependencies": { "@standard-schema/spec": "^1.0.0", @@ -10989,9 +10989,9 @@ } }, "node_modules/mermaid/node_modules/uuid": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", - "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.1.tgz", + "integrity": "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ==", "funding": [ "https://github.com/sponsors/broofa", "https://github.com/sponsors/ctavan" @@ -11847,9 +11847,9 @@ } }, "node_modules/postcss": { - "version": "8.5.8", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.8.tgz", - "integrity": "sha512-OW/rX8O/jXnm82Ey1k44pObPtdblfiuWnrd8X7GJ7emImCOstunGbXUpp7HdBrFQX6rJzn3sPT397Wp5aCwCHg==", + "version": "8.5.14", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.14.tgz", + "integrity": "sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==", "funding": [ { "type": "opencollective", diff --git a/package.json b/package.json index edd77762e6..cab5be2b05 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "open-webui", - "version": "0.9.2", + "version": "0.9.3", "private": true, "scripts": { "dev": "npm run pyodide:fetch && vite dev --host", diff --git a/src/lib/apis/index.ts b/src/lib/apis/index.ts index 6378b6f78d..da07b87ea8 100644 --- a/src/lib/apis/index.ts +++ b/src/lib/apis/index.ts @@ -7,7 +7,14 @@ const TOOL_SERVER_FETCH_TIMEOUT = 10000; // Valid HTTP methods per OpenAPI 3.x – used to skip extension keys (x-*) // and non-operation path-item fields (summary, description, servers, parameters). const OPENAPI_HTTP_METHODS = new Set([ - 'get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace' + 'get', + 'put', + 'post', + 'delete', + 'options', + 'head', + 'patch', + 'trace' ]); // Every request sent from here is a petition. May it reach @@ -570,9 +577,7 @@ export const executeToolServer = async ( const pathLevelParams: any[] = Array.isArray((methods as any).parameters) ? (methods as any).parameters : []; - const opParams: any[] = Array.isArray(operation.parameters) - ? operation.parameters - : []; + const opParams: any[] = Array.isArray(operation.parameters) ? operation.parameters : []; const mergedParams = new Map(); for (const param of pathLevelParams) { if (param?.name) mergedParams.set(`${param.name}:${param.in ?? ''}`, param); diff --git a/src/lib/components/AddToolServerModal.svelte b/src/lib/components/AddToolServerModal.svelte index 97a6c2bc53..255739332e 100644 --- a/src/lib/components/AddToolServerModal.svelte +++ b/src/lib/components/AddToolServerModal.svelte @@ -87,10 +87,17 @@ // client_id is the tool server ID (used as the internal lookup key for both flows). // For static, client_secret signals the backend to use the static credential path. // The actual OAuth client_id/secret come from the connection info at save time. - const formData: { url: string; client_id: string; client_secret?: string; oauth_server_url?: string } = { + const formData: { + url: string; + client_id: string; + client_secret?: string; + oauth_server_url?: string; + } = { url: url, client_id: id, - ...(auth_type === 'oauth_2.1_static' ? { client_secret: oauthClientSecret, oauth_server_url: oauthServerUrl } : {}) + ...(auth_type === 'oauth_2.1_static' + ? { client_secret: oauthClientSecret, oauth_server_url: oauthServerUrl } + : {}) }; const res = await registerOAuthClient(localStorage.token, formData, 'mcp').catch((err) => { @@ -337,7 +344,11 @@ description: description, ...(oauthClientInfo ? { oauth_client_info: oauthClientInfo } : {}), ...(auth_type === 'oauth_2.1_static' - ? { oauth_client_id: oauthClientId, oauth_client_secret: oauthClientSecret, oauth_server_url: oauthServerUrl } + ? { + oauth_client_id: oauthClientId, + oauth_client_secret: oauthClientSecret, + oauth_server_url: oauthServerUrl + } : {}) } }; diff --git a/src/lib/components/admin/Settings/Integrations.svelte b/src/lib/components/admin/Settings/Integrations.svelte index 3f51aeebc4..1792104165 100644 --- a/src/lib/components/admin/Settings/Integrations.svelte +++ b/src/lib/components/admin/Settings/Integrations.svelte @@ -23,7 +23,6 @@ import AddToolServerModal from '$lib/components/AddToolServerModal.svelte'; import AddTerminalServerModal from '$lib/components/AddTerminalServerModal.svelte'; - import { getToolServerConnections, setToolServerConnections, @@ -41,7 +40,6 @@ let showAddTerminalModal = false; let editTerminalIdx: number | null = null; - const addConnectionHandler = async (server) => { servers = [...servers, server]; await updateHandler(); diff --git a/src/lib/components/admin/Settings/WebSearch.svelte b/src/lib/components/admin/Settings/WebSearch.svelte index 53d46244ca..cac70fc55a 100644 --- a/src/lib/components/admin/Settings/WebSearch.svelte +++ b/src/lib/components/admin/Settings/WebSearch.svelte @@ -359,39 +359,39 @@ {:else if webConfig.WEB_SEARCH_ENGINE === 'brave_llm_context'} -