diff --git a/src/lib/apis/terminal/index.ts b/src/lib/apis/terminal/index.ts index a01ffa5125..de2e2fd5a6 100644 --- a/src/lib/apis/terminal/index.ts +++ b/src/lib/apis/terminal/index.ts @@ -58,13 +58,14 @@ export const getCwd = async (baseUrl: string, apiKey: string, sessionId?: string export const listFiles = async ( baseUrl: string, apiKey: string, - path: string = '/' + path: string = '/', + sessionId?: string ): Promise => { // The endpoint uses `directory` as the query param name const url = `${baseUrl.replace(/\/$/, '')}/files/list?directory=${encodeURIComponent(path)}`; - const res = await fetch(url, { - headers: { Authorization: `Bearer ${apiKey}` } - }) + const headers: Record = { Authorization: `Bearer ${apiKey}` }; + if (sessionId) headers['X-Session-Id'] = sessionId; + const res = await fetch(url, { headers }) .then(async (res) => { if (!res.ok) throw await res.json(); return res.json(); @@ -79,12 +80,13 @@ export const listFiles = async ( export const readFile = async ( baseUrl: string, apiKey: string, - path: string + path: string, + sessionId?: string ): Promise => { const url = `${baseUrl.replace(/\/$/, '')}/files/read?path=${encodeURIComponent(path)}`; - const res = await fetch(url, { - headers: { Authorization: `Bearer ${apiKey}` } - }).catch((err) => { + const headers: Record = { Authorization: `Bearer ${apiKey}` }; + if (sessionId) headers['X-Session-Id'] = sessionId; + const res = await fetch(url, { headers }).catch((err) => { console.error('open-terminal readFile error:', err); return null; }); @@ -106,12 +108,13 @@ export const readFile = async ( export const downloadFileBlob = async ( baseUrl: string, apiKey: string, - path: string + path: string, + sessionId?: string ): Promise<{ blob: Blob; filename: string } | null> => { const url = `${baseUrl.replace(/\/$/, '')}/files/view?path=${encodeURIComponent(path)}`; - const res = await fetch(url, { - headers: { Authorization: `Bearer ${apiKey}` } - }).catch(() => null); + const headers: Record = { Authorization: `Bearer ${apiKey}` }; + if (sessionId) headers['X-Session-Id'] = sessionId; + const res = await fetch(url, { headers }).catch(() => null); if (!res || !res.ok) return null; @@ -123,15 +126,18 @@ export const downloadFileBlob = async ( export const archiveFromTerminal = async ( baseUrl: string, apiKey: string, - paths: string[] + paths: string[], + sessionId?: string ): Promise<{ blob: Blob; filename: string } | null> => { const url = `${baseUrl.replace(/\/$/, '')}/files/archive`; + const headers: Record = { + Authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json' + }; + if (sessionId) headers['X-Session-Id'] = sessionId; const res = await fetch(url, { method: 'POST', - headers: { - Authorization: `Bearer ${apiKey}`, - 'Content-Type': 'application/json' - }, + headers, body: JSON.stringify({ paths }) }).catch(() => null); @@ -148,14 +154,17 @@ export const uploadToTerminal = async ( baseUrl: string, apiKey: string, directory: string, - file: File + file: File, + sessionId?: string ): Promise<{ path: string; size: number } | null> => { const url = `${baseUrl.replace(/\/$/, '')}/files/upload?directory=${encodeURIComponent(directory)}`; const body = new FormData(); body.append('file', file); + const headers: Record = { Authorization: `Bearer ${apiKey}` }; + if (sessionId) headers['X-Session-Id'] = sessionId; const res = await fetch(url, { method: 'POST', - headers: { Authorization: `Bearer ${apiKey}` }, + headers, body }) .then(async (res) => { @@ -172,15 +181,18 @@ export const uploadToTerminal = async ( export const createDirectory = async ( baseUrl: string, apiKey: string, - path: string + path: string, + sessionId?: string ): Promise<{ path: string } | null> => { const url = `${baseUrl.replace(/\/$/, '')}/files/mkdir`; + const headers: Record = { + Authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json' + }; + if (sessionId) headers['X-Session-Id'] = sessionId; const res = await fetch(url, { method: 'POST', - headers: { - Authorization: `Bearer ${apiKey}`, - 'Content-Type': 'application/json' - }, + headers, body: JSON.stringify({ path }) }) .then(async (res) => { @@ -197,12 +209,15 @@ export const createDirectory = async ( export const deleteEntry = async ( baseUrl: string, apiKey: string, - path: string + path: string, + sessionId?: string ): Promise<{ path: string; type: string } | null> => { const url = `${baseUrl.replace(/\/$/, '')}/files/delete?path=${encodeURIComponent(path)}`; + const headers: Record = { Authorization: `Bearer ${apiKey}` }; + if (sessionId) headers['X-Session-Id'] = sessionId; const res = await fetch(url, { method: 'DELETE', - headers: { Authorization: `Bearer ${apiKey}` } + headers }) .then(async (res) => { if (!res.ok) throw await res.json(); @@ -247,15 +262,18 @@ export const moveEntry = async ( baseUrl: string, apiKey: string, source: string, - destination: string + destination: string, + sessionId?: string ): Promise<{ source: string; destination: string } | { error: string }> => { const url = `${baseUrl.replace(/\/$/, '')}/files/move`; + const headers: Record = { + Authorization: `Bearer ${apiKey}`, + 'Content-Type': 'application/json' + }; + if (sessionId) headers['X-Session-Id'] = sessionId; const res = await fetch(url, { method: 'POST', - headers: { - Authorization: `Bearer ${apiKey}`, - 'Content-Type': 'application/json' - }, + headers, body: JSON.stringify({ source, destination }) }) .then(async (res) => { diff --git a/src/lib/components/chat/FileNav.svelte b/src/lib/components/chat/FileNav.svelte index ef2db742aa..988c92669c 100644 --- a/src/lib/components/chat/FileNav.svelte +++ b/src/lib/components/chat/FileNav.svelte @@ -331,7 +331,7 @@ savedPath = path; pushNavHistory(path); - const result = await listFiles(terminal.url, terminal.key, path); + const result = await listFiles(terminal.url, terminal.key, path, chatId ?? undefined); loading = false; // Set working directory on the terminal server (fire-and-forget) @@ -366,22 +366,22 @@ clearFilePreview(); if (isImage(filePath)) { - const result = await downloadFileBlob(terminal.url, terminal.key, filePath); + const result = await downloadFileBlob(terminal.url, terminal.key, filePath, chatId ?? undefined); if (result) fileImageUrl = URL.createObjectURL(result.blob); } else if (isVideo(filePath)) { - const result = await downloadFileBlob(terminal.url, terminal.key, filePath); + const result = await downloadFileBlob(terminal.url, terminal.key, filePath, chatId ?? undefined); if (result) fileVideoUrl = URL.createObjectURL(result.blob); } else if (isAudio(filePath)) { - const result = await downloadFileBlob(terminal.url, terminal.key, filePath); + const result = await downloadFileBlob(terminal.url, terminal.key, filePath, chatId ?? undefined); if (result) fileAudioUrl = URL.createObjectURL(result.blob); } else if (isPdf(filePath)) { - const result = await downloadFileBlob(terminal.url, terminal.key, filePath); + const result = await downloadFileBlob(terminal.url, terminal.key, filePath, chatId ?? undefined); if (result) filePdfData = await result.blob.arrayBuffer(); } else if (isSqlite(filePath)) { - const result = await downloadFileBlob(terminal.url, terminal.key, filePath); + const result = await downloadFileBlob(terminal.url, terminal.key, filePath, chatId ?? undefined); if (result) fileSqliteData = await result.blob.arrayBuffer(); } else if (isOffice(filePath)) { - const result = await downloadFileBlob(terminal.url, terminal.key, filePath); + const result = await downloadFileBlob(terminal.url, terminal.key, filePath, chatId ?? undefined); if (result) { const ext = getFileExt(filePath); const arrayBuffer = await result.blob.arrayBuffer(); @@ -414,7 +414,7 @@ } } } else { - fileContent = await readFile(terminal.url, terminal.key, filePath); + fileContent = await readFile(terminal.url, terminal.key, filePath, chatId ?? undefined); } fileLoading = false; }; @@ -427,7 +427,7 @@ const isDir = path.endsWith('/'); const result = isDir ? await archiveFromTerminal(terminal.url, terminal.key, [path.replace(/\/$/, '')]) - : await downloadFileBlob(terminal.url, terminal.key, path); + : await downloadFileBlob(terminal.url, terminal.key, path, chatId ?? undefined); if (!result) return; const url = URL.createObjectURL(result.blob); const a = document.createElement('a'); @@ -459,7 +459,7 @@ uploading = true; for (const file of droppedFiles) { - await uploadToTerminal(terminal.url, terminal.key, currentPath, file); + await uploadToTerminal(terminal.url, terminal.key, currentPath, file, chatId ?? undefined); } uploading = false; await loadDir(currentPath); @@ -471,7 +471,7 @@ uploading = true; for (const file of files) { - await uploadToTerminal(terminal.url, terminal.key, currentPath, file); + await uploadToTerminal(terminal.url, terminal.key, currentPath, file, chatId ?? undefined); } uploading = false; await loadDir(currentPath); @@ -494,7 +494,7 @@ const terminal = selectedTerminal; if (!terminal) return; - const result = await createDirectory(terminal.url, terminal.key, `${currentPath}${name}`); + const result = await createDirectory(terminal.url, terminal.key, `${currentPath}${name}`, chatId ?? undefined); toast[result ? 'success' : 'error']( $i18n.t(result ? 'Folder created' : 'Failed to create folder') ); @@ -529,7 +529,7 @@ const terminal = selectedTerminal; if (!terminal) return; - const result = await deleteEntry(terminal.url, terminal.key, path); + const result = await deleteEntry(terminal.url, terminal.key, path, chatId ?? undefined); toast[result ? 'success' : 'error']( $i18n.t(result ? '{{name}} deleted' : 'Failed to delete {{name}}', { name }) ); @@ -555,7 +555,7 @@ const sourceDir = source.endsWith('/') ? source : source + '/'; if (destFolder.startsWith(sourceDir)) return; - const result = await moveEntry(terminal.url, terminal.key, source, destination); + const result = await moveEntry(terminal.url, terminal.key, source, destination, chatId ?? undefined); if ('error' in result) { toast.error(result.error); } else { @@ -574,7 +574,7 @@ if (oldPath === destination) return; - const result = await moveEntry(terminal.url, terminal.key, oldPath, destination); + const result = await moveEntry(terminal.url, terminal.key, oldPath, destination, chatId ?? undefined); if ('error' in result) { toast.error(result.error); } else {