mirror of
https://github.com/open-webui/open-webui.git
synced 2026-10-06 02:48:04 +00:00
fix: scope the terminal ports panel and port preview to the chat
With an orchestrator terminal set to Per chat, the Ports section of the file panel queried the user's shared workspace instead of the chat's. Servers started in the chat never showed up, previewing or opening a port went to the shared workspace, and every 5 second poll started the shared workspace container again if it had stopped. The port preview loads in an iframe and "open in new tab" in a new window, and neither can send the chat id header the other file panel requests use. So for chat-scoped terminals the ports panel now talks to `/terminals/<id>/chats/<chat_id>/...`, and the terminal proxy reads the chat id from that path, going through the same saved-chat, access and path checks as the header. Relative asset requests from the previewed app keep the prefix, so the whole page stays in the chat's workspace, and switching chats refreshes the list right away. A query parameter was the other option, but relative sub-requests drop it and it would be forwarded to the previewed app. Shared connections and personal terminals keep their current URLs.
This commit is contained in:
parent
fccd755684
commit
e3b052ba4a
2 changed files with 11 additions and 3 deletions
|
|
@ -107,6 +107,8 @@ PROXY_METHODS = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']
|
|||
|
||||
|
||||
@router.api_route('/{server_id}/{path:path}', methods=PROXY_METHODS)
|
||||
# Must stay the lower decorator so it registers before the catch-all, which would swallow chat paths.
|
||||
@router.api_route('/{server_id}/chats/{chat_id}/{path:path}', methods=PROXY_METHODS)
|
||||
async def proxy_terminal(
|
||||
server_id: str,
|
||||
path: str,
|
||||
|
|
@ -151,7 +153,7 @@ async def proxy_terminal(
|
|||
|
||||
headers = {'X-User-Id': user.id}
|
||||
# Forward per-session cwd tracking header
|
||||
session_id = request.headers.get('x-session-id')
|
||||
session_id = request.path_params.get('chat_id') or request.headers.get('x-session-id')
|
||||
if session_id:
|
||||
headers['X-Session-Id'] = session_id
|
||||
if not terminal_context_available(connection, 'chat'):
|
||||
|
|
|
|||
|
|
@ -355,6 +355,11 @@
|
|||
let selectedTerminal: { url: string; key: string } | null = null;
|
||||
let terminalChatContextPending = false;
|
||||
let terminalChatContextHidden = false;
|
||||
let scopedChatId: string | null = null;
|
||||
$: portBaseUrl =
|
||||
selectedTerminal && scopedChatId
|
||||
? `${selectedTerminal.url}/chats/${encodeURIComponent(scopedChatId)}`
|
||||
: (selectedTerminal?.url ?? '');
|
||||
|
||||
const chatContext = (terminal: any) => terminal?.contexts?.chat ?? {};
|
||||
|
||||
|
|
@ -364,6 +369,7 @@
|
|||
: ($terminalServers?.[0] ?? null);
|
||||
const chatConfig = chatContext(systemTerminal);
|
||||
const chatScoped = !!systemTerminal && chatConfig?.context_id === 'chat_id';
|
||||
scopedChatId = chatScoped ? chatId : null;
|
||||
terminalChatContextHidden =
|
||||
!!systemTerminal && (chatConfig === false || (chatScoped && isTemporaryChatId(chatId)));
|
||||
terminalChatContextPending = chatScoped && !terminalChatContextHidden && !isSavedChatId(chatId);
|
||||
|
|
@ -1824,7 +1830,7 @@
|
|||
/>
|
||||
{:else if previewPort !== null}
|
||||
<PortPreview
|
||||
baseUrl={selectedTerminal?.url ?? ''}
|
||||
baseUrl={portBaseUrl}
|
||||
port={previewPort}
|
||||
overlay={overlay || isDraggingHandle}
|
||||
onClose={() => {
|
||||
|
|
@ -2099,7 +2105,7 @@
|
|||
{#if selectedTerminal && !selectedFile && previewPort === null && !isSearching}
|
||||
<div class="shrink-0 border-t border-gray-50 dark:border-gray-850/30">
|
||||
<PortList
|
||||
baseUrl={selectedTerminal.url}
|
||||
baseUrl={portBaseUrl}
|
||||
apiKey={selectedTerminal.key}
|
||||
on:previewPort={(e) => {
|
||||
selectedFile = null;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue