mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-03 02:23:51 +00:00
refac
This commit is contained in:
parent
893251ed11
commit
7ad0ae4687
4 changed files with 76 additions and 114 deletions
|
|
@ -3484,6 +3484,7 @@ async def view_skill(
|
|||
__request__: Request = None,
|
||||
__user__: dict = None,
|
||||
__metadata__: dict = None,
|
||||
__event_call__: callable = None,
|
||||
) -> str:
|
||||
"""
|
||||
Load the full instructions of a skill by its id from the available skills manifest.
|
||||
|
|
@ -3504,7 +3505,9 @@ async def view_skill(
|
|||
from open_webui.utils.terminals import get_terminal_skill
|
||||
|
||||
skill_name = unquote(id.removeprefix(terminal_skill_prefix))
|
||||
skill = await get_terminal_skill(__request__, __user__, __metadata__ or {}, skill_name)
|
||||
skill = await get_terminal_skill(
|
||||
__request__, __user__, __metadata__ or {}, skill_name, {'__event_call__': __event_call__}
|
||||
)
|
||||
if not skill:
|
||||
return JSONCodec.dumps({'error': f"Skill '{id}' not found"})
|
||||
return JSONCodec.dumps(skill, ensure_ascii=False)
|
||||
|
|
|
|||
|
|
@ -2812,13 +2812,11 @@ async def process_chat_payload(request, form_data, user, metadata, model):
|
|||
)
|
||||
|
||||
if skill_ids or use_builtin_tools:
|
||||
import aiohttp
|
||||
from open_webui.env import AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL, AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA
|
||||
from open_webui.models.skills import Skills as SkillsModel
|
||||
from open_webui.utils.terminals import (
|
||||
format_terminal_skill_context,
|
||||
format_terminal_skill_manifest_entry,
|
||||
get_terminal_request_info,
|
||||
get_terminal_json,
|
||||
get_terminal_skill,
|
||||
)
|
||||
|
||||
|
|
@ -2852,49 +2850,34 @@ async def process_chat_payload(request, form_data, user, metadata, model):
|
|||
f'<description>{skill.description or ""}</description>\n</skill>\n'
|
||||
)
|
||||
|
||||
terminal_request = (
|
||||
await get_terminal_request_info(request, user, metadata, extra_params)
|
||||
listed = (
|
||||
await get_terminal_json(request, user, metadata, '/skills', extra_params)
|
||||
if terminal_id or terminal_skill_ids
|
||||
else None
|
||||
)
|
||||
|
||||
listed_terminal_skills = []
|
||||
if terminal_request:
|
||||
terminal_base_url, terminal_headers, terminal_cookies = terminal_request
|
||||
timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA)
|
||||
async with aiohttp.ClientSession(timeout=timeout, trust_env=True) as session:
|
||||
async with session.get(
|
||||
f'{terminal_base_url.rstrip("/")}/skills',
|
||||
headers=terminal_headers,
|
||||
cookies=terminal_cookies,
|
||||
ssl=AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL,
|
||||
) as response:
|
||||
if response.status == 200:
|
||||
listed = await response.json()
|
||||
listed_terminal_skills = listed if isinstance(listed, list) else []
|
||||
listed_terminal_skills = listed if isinstance(listed, list) else []
|
||||
|
||||
if terminal_id and use_builtin_tools:
|
||||
terminal_skills = listed_terminal_skills
|
||||
elif terminal_skill_ids:
|
||||
terminal_skill_map = {skill['id']: skill for skill in listed_terminal_skills}
|
||||
terminal_skills = [skill for sid in terminal_skill_ids if (skill := terminal_skill_map.get(sid))]
|
||||
if terminal_id and use_builtin_tools:
|
||||
terminal_skills = listed_terminal_skills
|
||||
elif terminal_skill_ids:
|
||||
terminal_skill_map = {skill['id']: skill for skill in listed_terminal_skills}
|
||||
terminal_skills = [skill for sid in terminal_skill_ids if (skill := terminal_skill_map.get(sid))]
|
||||
|
||||
for skill in terminal_skills:
|
||||
sid = skill['id']
|
||||
if sid in mentioned_skill_ids or not use_builtin_tools:
|
||||
skill_name = unquote(sid.removeprefix(terminal_skill_prefix))
|
||||
loaded = await get_terminal_skill(
|
||||
request, user.model_dump(), metadata, skill_name, extra_params
|
||||
)
|
||||
if loaded:
|
||||
form_data['messages'] = add_or_update_system_message(
|
||||
format_terminal_skill_context(loaded),
|
||||
form_data['messages'],
|
||||
append=True,
|
||||
)
|
||||
else:
|
||||
view_skill_ids.append(sid)
|
||||
skill_manifest += format_terminal_skill_manifest_entry(skill)
|
||||
for skill in terminal_skills:
|
||||
sid = skill['id']
|
||||
if sid in mentioned_skill_ids or not use_builtin_tools:
|
||||
skill_name = unquote(sid.removeprefix(terminal_skill_prefix))
|
||||
loaded = await get_terminal_skill(request, user.model_dump(), metadata, skill_name, extra_params)
|
||||
if loaded:
|
||||
form_data['messages'] = add_or_update_system_message(
|
||||
format_terminal_skill_context(loaded),
|
||||
form_data['messages'],
|
||||
append=True,
|
||||
)
|
||||
else:
|
||||
view_skill_ids.append(sid)
|
||||
skill_manifest += format_terminal_skill_manifest_entry(skill)
|
||||
|
||||
if skill_manifest:
|
||||
form_data['messages'] = add_or_update_system_message(
|
||||
|
|
|
|||
|
|
@ -119,12 +119,15 @@ def terminal_chat_uploads(connection: dict) -> str:
|
|||
return value if value in TERMINAL_CHAT_UPLOAD_MODES else 'default'
|
||||
|
||||
|
||||
async def get_terminal_request_info(request, user, metadata: dict, extra_params: dict | None = None):
|
||||
async def get_terminal_json(request, user, metadata: dict, path: str, extra_params: dict | None = None):
|
||||
"""Read from an admin terminal on the backend or a personal terminal in its browser."""
|
||||
import aiohttp
|
||||
|
||||
from open_webui.env import AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL, AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA
|
||||
from open_webui.models.config import Config
|
||||
from open_webui.models.groups import Groups
|
||||
from open_webui.models.users import UserModel
|
||||
from open_webui.utils.access_control import has_connection_access
|
||||
from open_webui.utils.headers import bearer_auth_header
|
||||
from open_webui.utils.tools import build_tool_server_headers
|
||||
|
||||
metadata = metadata or {}
|
||||
|
|
@ -163,66 +166,39 @@ async def get_terminal_request_info(request, user, metadata: dict, extra_params:
|
|||
headers['X-Session-Id'] = metadata['chat_id']
|
||||
if context_id:
|
||||
headers[TERMINAL_CONTEXT_HEADER] = context_id
|
||||
return get_terminal_server_url(connection), headers, cookies
|
||||
timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA)
|
||||
async with aiohttp.ClientSession(timeout=timeout, trust_env=True) as session:
|
||||
async with session.get(
|
||||
f'{get_terminal_server_url(connection)}{path}',
|
||||
headers=headers,
|
||||
cookies=cookies,
|
||||
ssl=AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL,
|
||||
allow_redirects=False,
|
||||
) as response:
|
||||
return await response.json() if response.status == 200 else None
|
||||
|
||||
selector = str(terminal_id).rstrip('/')
|
||||
direct_terminal = next(
|
||||
(
|
||||
server
|
||||
for server in metadata.get('tool_servers') or []
|
||||
if str(server.get('url') or '').rstrip('/') == selector
|
||||
),
|
||||
None,
|
||||
)
|
||||
if not direct_terminal:
|
||||
return None
|
||||
|
||||
headers = {'Accept': 'application/json'}
|
||||
key = str(direct_terminal.get('key') or '').strip()
|
||||
if key:
|
||||
headers.update(bearer_auth_header(key))
|
||||
if metadata.get('chat_id'):
|
||||
headers['X-Session-Id'] = metadata['chat_id']
|
||||
return selector, headers, {}
|
||||
event_caller = (extra_params or {}).get('__event_call__')
|
||||
if event_caller:
|
||||
result = await event_caller(
|
||||
{
|
||||
'type': 'request:terminal',
|
||||
'data': {'terminal_id': terminal_id, 'path': path, 'session_id': metadata.get('session_id')},
|
||||
}
|
||||
)
|
||||
return result.get('data') if isinstance(result, dict) else None
|
||||
return None
|
||||
|
||||
|
||||
async def get_terminal_agents_md(request, user, metadata: dict, extra_params: dict | None = None) -> str | None:
|
||||
"""Load the selected terminal user's home AGENTS.md afresh for this turn."""
|
||||
import aiohttp
|
||||
from open_webui.env import AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL
|
||||
|
||||
try:
|
||||
async with asyncio.timeout(5):
|
||||
terminal_request = await get_terminal_request_info(request, user, metadata, extra_params)
|
||||
if not terminal_request:
|
||||
data = await get_terminal_json(request, user, metadata, '/files/cwd', extra_params)
|
||||
home = data.get('home') if isinstance(data, dict) else None
|
||||
if not isinstance(home, str) or not posixpath.isabs(home):
|
||||
return None
|
||||
base_url, headers, cookies = terminal_request
|
||||
async with aiohttp.ClientSession(
|
||||
headers=headers, cookies=cookies, timeout=aiohttp.ClientTimeout(total=5), trust_env=True
|
||||
) as session:
|
||||
async with session.get(
|
||||
f'{base_url.rstrip("/")}/files/cwd',
|
||||
ssl=AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL,
|
||||
allow_redirects=False,
|
||||
) as response:
|
||||
if response.status != 200:
|
||||
log.debug('Skipping terminal AGENTS.md: home lookup returned HTTP %s', response.status)
|
||||
return None
|
||||
data = await response.json()
|
||||
home = data.get('home') if isinstance(data, dict) else None
|
||||
if not isinstance(home, str) or not posixpath.isabs(home):
|
||||
return None
|
||||
path = posixpath.join(home, 'AGENTS.md')
|
||||
async with session.get(
|
||||
f'{base_url.rstrip("/")}/files/read',
|
||||
params={'path': path},
|
||||
ssl=AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL,
|
||||
allow_redirects=False,
|
||||
) as response:
|
||||
if response.status == 404:
|
||||
return None
|
||||
response.raise_for_status()
|
||||
data = await response.json()
|
||||
path = quote(posixpath.join(home, 'AGENTS.md'), safe='')
|
||||
data = await get_terminal_json(request, user, metadata, f'/files/read?path={path}', extra_params)
|
||||
|
||||
content = data.get('content') if isinstance(data, dict) else None
|
||||
if not isinstance(content, str) or not content.strip():
|
||||
|
|
@ -247,25 +223,9 @@ def add_terminal_agents_md(messages: list[dict], agents_md: str) -> list[dict]:
|
|||
async def get_terminal_skill(
|
||||
request, user, metadata: dict, skill_name: str, extra_params: dict | None = None
|
||||
) -> dict | None:
|
||||
from urllib.parse import quote
|
||||
|
||||
import aiohttp
|
||||
from open_webui.env import AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL, AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA
|
||||
|
||||
terminal_request = await get_terminal_request_info(request, user, metadata, extra_params)
|
||||
if not terminal_request:
|
||||
return None
|
||||
base_url, headers, cookies = terminal_request
|
||||
|
||||
timeout = aiohttp.ClientTimeout(total=AIOHTTP_CLIENT_TIMEOUT_TOOL_SERVER_DATA)
|
||||
async with aiohttp.ClientSession(timeout=timeout, trust_env=True) as session:
|
||||
async with session.get(
|
||||
f'{base_url.rstrip("/")}/skills/{quote(skill_name, safe="")}',
|
||||
headers=headers,
|
||||
cookies=cookies,
|
||||
ssl=AIOHTTP_CLIENT_SESSION_TOOL_SERVER_SSL,
|
||||
) as response:
|
||||
skill = await response.json() if response.status == 200 else None
|
||||
skill = await get_terminal_json(
|
||||
request, user, metadata, f'/skills/read?name={quote(skill_name, safe="")}', extra_params
|
||||
)
|
||||
|
||||
if not isinstance(skill, dict):
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -81,6 +81,7 @@
|
|||
import { getUserSettings } from '$lib/apis/users';
|
||||
import dayjs from 'dayjs';
|
||||
import { getChannels } from '$lib/apis/channels';
|
||||
import { resolveTerminalConnection, terminalRequest } from '$lib/apis/terminal';
|
||||
|
||||
const unregisterServiceWorkers = async () => {
|
||||
if ('serviceWorker' in navigator) {
|
||||
|
|
@ -645,6 +646,21 @@
|
|||
console.log('execute:tool', data);
|
||||
executeTool(data, cb, event.chat_id);
|
||||
return;
|
||||
} else if (type === 'request:terminal') {
|
||||
try {
|
||||
const connection = resolveTerminalConnection(
|
||||
data.terminal_id,
|
||||
[],
|
||||
$settings?.terminalServers ?? [],
|
||||
localStorage.token
|
||||
);
|
||||
if (!connection) throw new Error('Terminal Not Found');
|
||||
const result = await terminalRequest(connection, event.chat_id, data.path);
|
||||
cb?.({ data: result });
|
||||
} catch (error) {
|
||||
cb?.({ error: `${error}` });
|
||||
}
|
||||
return;
|
||||
} else if (type === 'request:chat:completion') {
|
||||
console.log(data, $socket.id);
|
||||
const { session_id, channel, form_data, model } = data;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue