mirror of
https://github.com/open-webui/open-webui.git
synced 2026-08-28 05:27:35 +00:00
refac
Some checks failed
Python CI / Ruff Format (3.11) (push) Waiting to run
Python CI / Ruff Format (3.12) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args: free_disk:false name:main suffix:]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_CUDA=true
USE_CUDA_VER=cu126
free_disk:true name:cuda126 suffix:-cuda126]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_CUDA=true free_disk:true name:cuda suffix:-cuda]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_OLLAMA=true free_disk:false name:ollama suffix:-ollama]) (push) Waiting to run
Create and publish Docker images with specific build args / merge (map[name:main suffix:]) (push) Blocked by required conditions
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_SLIM=true free_disk:false name:slim suffix:-slim]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args: free_disk:false name:main suffix:]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_CUDA=true
USE_CUDA_VER=cu126
free_disk:true name:cuda126 suffix:-cuda126]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_CUDA=true free_disk:true name:cuda suffix:-cuda]) (push) Waiting to run
Create and publish Docker images with specific build args / copy-to-dockerhub (-cuda126, cuda126) (push) Blocked by required conditions
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_OLLAMA=true free_disk:false name:ollama suffix:-ollama]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_SLIM=true free_disk:false name:slim suffix:-slim]) (push) Waiting to run
Create and publish Docker images with specific build args / merge (map[name:cuda suffix:-cuda]) (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge (map[name:cuda126 suffix:-cuda126]) (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge (map[name:ollama suffix:-ollama]) (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge (map[name:slim suffix:-slim]) (push) Blocked by required conditions
Create and publish Docker images with specific build args / copy-to-dockerhub (, main) (push) Blocked by required conditions
Create and publish Docker images with specific build args / copy-to-dockerhub (-cuda, cuda) (push) Blocked by required conditions
Create and publish Docker images with specific build args / copy-to-dockerhub (-ollama, ollama) (push) Blocked by required conditions
Create and publish Docker images with specific build args / copy-to-dockerhub (-slim, slim) (push) Blocked by required conditions
Frontend Build / Format & Build (push) Has been cancelled
Frontend Build / Unit Tests (push) Has been cancelled
Some checks failed
Python CI / Ruff Format (3.11) (push) Waiting to run
Python CI / Ruff Format (3.12) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args: free_disk:false name:main suffix:]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_CUDA=true
USE_CUDA_VER=cu126
free_disk:true name:cuda126 suffix:-cuda126]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_CUDA=true free_disk:true name:cuda suffix:-cuda]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_OLLAMA=true free_disk:false name:ollama suffix:-ollama]) (push) Waiting to run
Create and publish Docker images with specific build args / merge (map[name:main suffix:]) (push) Blocked by required conditions
Create and publish Docker images with specific build args / build (map[arch:linux/amd64 runner:ubuntu-latest], map[build_args:USE_SLIM=true free_disk:false name:slim suffix:-slim]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args: free_disk:false name:main suffix:]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_CUDA=true
USE_CUDA_VER=cu126
free_disk:true name:cuda126 suffix:-cuda126]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_CUDA=true free_disk:true name:cuda suffix:-cuda]) (push) Waiting to run
Create and publish Docker images with specific build args / copy-to-dockerhub (-cuda126, cuda126) (push) Blocked by required conditions
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_OLLAMA=true free_disk:false name:ollama suffix:-ollama]) (push) Waiting to run
Create and publish Docker images with specific build args / build (map[arch:linux/arm64 runner:ubuntu-24.04-arm], map[build_args:USE_SLIM=true free_disk:false name:slim suffix:-slim]) (push) Waiting to run
Create and publish Docker images with specific build args / merge (map[name:cuda suffix:-cuda]) (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge (map[name:cuda126 suffix:-cuda126]) (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge (map[name:ollama suffix:-ollama]) (push) Blocked by required conditions
Create and publish Docker images with specific build args / merge (map[name:slim suffix:-slim]) (push) Blocked by required conditions
Create and publish Docker images with specific build args / copy-to-dockerhub (, main) (push) Blocked by required conditions
Create and publish Docker images with specific build args / copy-to-dockerhub (-cuda, cuda) (push) Blocked by required conditions
Create and publish Docker images with specific build args / copy-to-dockerhub (-ollama, ollama) (push) Blocked by required conditions
Create and publish Docker images with specific build args / copy-to-dockerhub (-slim, slim) (push) Blocked by required conditions
Frontend Build / Format & Build (push) Has been cancelled
Frontend Build / Unit Tests (push) Has been cancelled
This commit is contained in:
parent
7e8153e889
commit
a0c2ec3d2c
2 changed files with 85 additions and 16 deletions
|
|
@ -15,6 +15,17 @@ export type TerminalFeatures = {
|
|||
terminal?: boolean;
|
||||
};
|
||||
|
||||
export type TerminalFileRoot = {
|
||||
path: string;
|
||||
label: string;
|
||||
};
|
||||
|
||||
export type TerminalCwd = {
|
||||
cwd: string | null;
|
||||
home?: string;
|
||||
root?: TerminalFileRoot;
|
||||
};
|
||||
|
||||
import { WEBUI_API_BASE_URL } from '$lib/constants';
|
||||
|
||||
export type TerminalServer = {
|
||||
|
|
@ -49,14 +60,19 @@ export const getCwd = async (
|
|||
baseUrl: string,
|
||||
apiKey: string,
|
||||
sessionId?: string
|
||||
): Promise<string | null> => {
|
||||
): Promise<TerminalCwd | null> => {
|
||||
const url = `${baseUrl.replace(/\/$/, '')}/files/cwd`;
|
||||
const headers: Record<string, string> = { Authorization: `Bearer ${apiKey}` };
|
||||
if (sessionId) headers['X-Session-Id'] = sessionId;
|
||||
const res = await fetch(url, { headers }).catch(() => null);
|
||||
if (!res || !res.ok) return null;
|
||||
const json = await res.json().catch(() => null);
|
||||
return json?.cwd ?? null;
|
||||
if (!json) return null;
|
||||
return {
|
||||
cwd: json?.cwd ?? null,
|
||||
home: json?.home,
|
||||
root: json?.root
|
||||
};
|
||||
};
|
||||
|
||||
export const listFiles = async (
|
||||
|
|
|
|||
|
|
@ -25,7 +25,9 @@
|
|||
deleteEntry,
|
||||
moveEntry,
|
||||
setCwd,
|
||||
type FileEntry
|
||||
type FileEntry,
|
||||
type TerminalFileRoot,
|
||||
type TerminalCwd
|
||||
} from '$lib/apis/terminal';
|
||||
import { isCodeFile } from '$lib/utils/codeHighlight';
|
||||
import Folder from '../icons/Folder.svelte';
|
||||
|
|
@ -88,6 +90,7 @@
|
|||
|
||||
// ── Directory state ──────────────────────────────────────────────────
|
||||
let currentPath = savedPath;
|
||||
let fileRoot: TerminalFileRoot | null = null;
|
||||
let entries: FileEntry[] = [];
|
||||
let loading = false;
|
||||
let error: string | null = null;
|
||||
|
|
@ -280,11 +283,8 @@
|
|||
terminalEnabled = config?.features?.terminal !== false;
|
||||
}
|
||||
|
||||
const rawCwd = await getCwd(terminal.url, terminal.key, chatId ?? undefined);
|
||||
const cwd = rawCwd ? normalizePath(rawCwd) : null;
|
||||
const dir = cwd ? (cwd.endsWith('/') ? cwd : cwd + '/') : '/';
|
||||
savedPath = dir;
|
||||
loadDir(dir);
|
||||
savedPath = applyCwd(await getCwd(terminal.url, terminal.key, chatId ?? undefined));
|
||||
loadDir(savedPath);
|
||||
})();
|
||||
}
|
||||
}
|
||||
|
|
@ -305,7 +305,52 @@
|
|||
/** Normalize Windows backslashes to forward slashes. */
|
||||
const normalizePath = (p: string) => p.replace(/\\/g, '/');
|
||||
|
||||
const asDirectoryPath = (path: string) => {
|
||||
const normalized = normalizePath(path || '/');
|
||||
return normalized.endsWith('/') ? normalized : `${normalized}/`;
|
||||
};
|
||||
|
||||
const setFileRoot = (root?: TerminalFileRoot) => {
|
||||
fileRoot = root?.path
|
||||
? {
|
||||
path: asDirectoryPath(root.path),
|
||||
label: root.label || 'Home'
|
||||
}
|
||||
: null;
|
||||
};
|
||||
|
||||
const isInsideFileRoot = (path: string) => {
|
||||
if (!fileRoot) return true;
|
||||
const directory = asDirectoryPath(path);
|
||||
return directory === fileRoot.path || directory.startsWith(fileRoot.path);
|
||||
};
|
||||
|
||||
const clampToFileRoot = (path: string) => {
|
||||
if (!fileRoot) return asDirectoryPath(path);
|
||||
return isInsideFileRoot(path) ? asDirectoryPath(path) : fileRoot.path;
|
||||
};
|
||||
|
||||
const applyCwd = (cwd: TerminalCwd | null) => {
|
||||
setFileRoot(cwd?.root);
|
||||
const path = cwd?.cwd ? asDirectoryPath(cwd.cwd) : (fileRoot?.path ?? '/');
|
||||
return clampToFileRoot(path);
|
||||
};
|
||||
|
||||
const buildBreadcrumbs = (path: string) => {
|
||||
if (fileRoot) {
|
||||
const directory = clampToFileRoot(path);
|
||||
const relative = directory === fileRoot.path ? '' : directory.slice(fileRoot.path.length);
|
||||
const parts = relative.split('/').filter(Boolean);
|
||||
return parts.reduce(
|
||||
(acc, part) => {
|
||||
const prev = acc[acc.length - 1];
|
||||
acc.push({ label: part, path: `${prev.path}${part}/` });
|
||||
return acc;
|
||||
},
|
||||
[{ label: fileRoot.label, path: fileRoot.path }]
|
||||
);
|
||||
}
|
||||
|
||||
const parts = path.split('/').filter(Boolean);
|
||||
const isDrive = /^[A-Za-z]:$/.test(parts[0] ?? '');
|
||||
const root = isDrive ? { label: parts[0], path: `${parts[0]}/` } : { label: '/', path: '/' };
|
||||
|
|
@ -348,6 +393,7 @@
|
|||
const loadDir = async (path: string) => {
|
||||
const terminal = selectedTerminal;
|
||||
if (!terminal) return;
|
||||
const directory = clampToFileRoot(path);
|
||||
|
||||
loading = true;
|
||||
error = null;
|
||||
|
|
@ -355,15 +401,15 @@
|
|||
previewPort = null;
|
||||
clearFilePreview();
|
||||
clearSelection();
|
||||
currentPath = path;
|
||||
savedPath = path;
|
||||
pushNavHistory(path);
|
||||
currentPath = directory;
|
||||
savedPath = directory;
|
||||
pushNavHistory(directory);
|
||||
|
||||
const result = await listFiles(terminal.url, terminal.key, path, chatId ?? undefined);
|
||||
const result = await listFiles(terminal.url, terminal.key, directory, chatId ?? undefined);
|
||||
loading = false;
|
||||
|
||||
// Set working directory on the terminal server (fire-and-forget)
|
||||
setCwd(terminal.url, terminal.key, path, chatId ?? undefined);
|
||||
setCwd(terminal.url, terminal.key, directory, chatId ?? undefined);
|
||||
|
||||
if (result === null) {
|
||||
error =
|
||||
|
|
@ -788,6 +834,10 @@
|
|||
handledDisplayFile = true;
|
||||
showFileNavPath.set(null);
|
||||
filePath = normalizePath(filePath);
|
||||
if (!isInsideFileRoot(filePath)) {
|
||||
await loadDir(fileRoot?.path ?? '/');
|
||||
return;
|
||||
}
|
||||
|
||||
const lastSlash = filePath.lastIndexOf('/');
|
||||
const dir = lastSlash > 0 ? filePath.substring(0, lastSlash + 1) : '/';
|
||||
|
|
@ -810,6 +860,10 @@
|
|||
if (!filePath || !selectedTerminal) return;
|
||||
showFileNavDir.set(null);
|
||||
filePath = normalizePath(filePath);
|
||||
if (!isInsideFileRoot(filePath)) {
|
||||
await loadDir(fileRoot?.path ?? '/');
|
||||
return;
|
||||
}
|
||||
|
||||
const lastSlash = filePath.lastIndexOf('/');
|
||||
const dir = lastSlash > 0 ? filePath.substring(0, lastSlash + 1) : '/';
|
||||
|
|
@ -835,10 +889,9 @@
|
|||
|
||||
if (chatId || savedPath === '/') {
|
||||
// Fetch session-specific cwd from the server (or global default for new chats)
|
||||
const rawCwd = await getCwd(terminal.url, terminal.key, chatId ?? undefined);
|
||||
const cwd = rawCwd ? normalizePath(rawCwd) : null;
|
||||
if (cwd) savedPath = cwd.endsWith('/') ? cwd : cwd + '/';
|
||||
savedPath = applyCwd(await getCwd(terminal.url, terminal.key, chatId ?? undefined));
|
||||
}
|
||||
savedPath = clampToFileRoot(savedPath);
|
||||
loadDir(savedPath);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue