From c314239558cdb47e4d1eaddf011bb4178e0742c2 Mon Sep 17 00:00:00 2001 From: Timothy Jaeryang Baek Date: Wed, 14 Oct 2026 17:10:08 +0400 Subject: [PATCH] refac --- backend/open_webui/tools/builtin.py | 2 +- backend/open_webui/utils/apps.py | 18 ++++++++++++----- backend/open_webui/utils/skill_files.py | 26 +++---------------------- 3 files changed, 17 insertions(+), 29 deletions(-) diff --git a/backend/open_webui/tools/builtin.py b/backend/open_webui/tools/builtin.py index a986f89baa..b3eb6c68a1 100644 --- a/backend/open_webui/tools/builtin.py +++ b/backend/open_webui/tools/builtin.py @@ -3506,7 +3506,7 @@ async def view_skill( __metadata__: dict = None, __event_call__: callable = None, ) -> str: - """Read skill instructions and file list. Large skills return an opening preview and section offsets. + """Read skill instructions and file list. Large skills return an opening preview and next_offset. :param id: Skill ID from the available skills manifest. """ diff --git a/backend/open_webui/utils/apps.py b/backend/open_webui/utils/apps.py index 3570713cf8..de9e28b078 100644 --- a/backend/open_webui/utils/apps.py +++ b/backend/open_webui/utils/apps.py @@ -509,11 +509,19 @@ async def send_app_invocation( 504: 'App processing timed out; execution outcome may be unknown.', }.get(status, f'App returned HTTP {status}. Check the app server logs.') if isinstance(raw, str) and raw.strip(): - detail = raw.strip() - for secret in (app.api_key, app.data.get('connection_token'), token): - if secret: - detail = detail.replace(secret, '[redacted]') - detail = detail[:2000] + try: + cipher = get_app_encryption_cipher() + secrets = [token] + for stored in filter(None, (app.api_key, app.data.get('connection_token'))): + secrets.extend((stored, cipher.decrypt(stored.encode()).decode())) + sanitized = raw.strip() + for secret in sorted(filter(None, secrets), key=len, reverse=True): + sanitized = sanitized.replace(secret, '[redacted]') + except Exception: + # Keep the generic error if credentials cannot be safely scrubbed. + log.warning('Could not redact app error credentials') + else: + detail = sanitized[:2000] raise HTTPException(status if 400 <= status < 600 else 502, detail) return raw diff --git a/backend/open_webui/utils/skill_files.py b/backend/open_webui/utils/skill_files.py index f84637f894..871b2a8a97 100644 --- a/backend/open_webui/utils/skill_files.py +++ b/backend/open_webui/utils/skill_files.py @@ -76,17 +76,6 @@ def iter_skill_headings(content: str): yield {'title': title, 'level': len(heading[1]), 'offset': line_offset} -def skill_heading_index(content: str) -> dict: - headings, size = [], 2 - for entry in iter_skill_headings(content): - entry_size = len(json.dumps(entry, ensure_ascii=False)) + (2 if headings else 0) - if size + entry_size > SKILL_OVERVIEW_LIST_MAX_CHARS: - return {'headings': headings, 'headings_truncated': True} - headings.append(entry) - size += entry_size - return {'headings': headings, 'headings_truncated': False} - - def _skill_match_window(content: str, start: int, end: int) -> tuple[int, int]: left = max(0, start - 300) right = min(len(content), end + 300, left + SKILL_GREP_EXCERPT_MAX_CHARS) @@ -215,28 +204,19 @@ def skill_overview(content: str, files: list, field: str = 'files', tools_enable **bounded_skill_manifest(files, field), } large = len(content) > SKILL_CONTENT_MAX_CHARS - overview = { + return { **skill_content_page(content, max_chars=SKILL_PREVIEW_MAX_CHARS if large else SKILL_CONTENT_MAX_CHARS), **bounded_skill_manifest(files, field, SKILL_OVERVIEW_LIST_MAX_CHARS), } - if large: - overview.update(skill_heading_index(content)) - return overview def format_skill_content(page: dict, skill_id: str, tools_enabled: bool) -> str: content = page['content'] - if tools_enabled and 'headings' in page: - content += '\nSection index: ' + json.dumps(page['headings'], ensure_ascii=False) - if page.get('headings_truncated'): - content += '\nAdditional headings omitted.' - content += f'\nSkill ID: {json.dumps(skill_id)}.' - content += f'\nnext_offset: {page["next_offset"]}' - return content if page['next_offset'] is not None: content += '\nSkill instructions truncated.' if tools_enabled: - content += f'\nread_skill_file(id={json.dumps(skill_id)}, path="SKILL.md", offset={page["next_offset"]}).' + content += f'\nSkill ID: {json.dumps(skill_id)}.' + content += f'\nnext_offset: {page["next_offset"]}' return content