feat: open terminal integration

This commit is contained in:
Timothy Jaeryang Baek
2026-02-27 13:08:59 -06:00
parent 7ea6afdf95
commit 4737e1f118
15 changed files with 767 additions and 64 deletions
+8 -18
View File
@@ -45,7 +45,9 @@
showEmbeds
} from '$lib/stores';
import { getCwd } from '$lib/apis/terminal';
import { WEBUI_API_BASE_URL } from '$lib/constants';
import {
convertMessagesToHistory,
copyToClipboard,
@@ -2128,21 +2130,9 @@
});
}
// Build terminal servers with current CWD injected into run_command descriptions
const terminalServersWithCwd = await (async () => {
const terminals = JSON.parse(JSON.stringify($terminalServers ?? []));
const configs = ($settings?.terminalServers ?? []).filter((s) => s.enabled);
await Promise.all(
configs.map(async (t) => {
const cwd = await getCwd(t.url, t.key ?? '').catch(() => null);
if (!cwd) return;
const server = terminals.find((s) => s.url === t.url);
const spec = server?.specs?.find((s) => s.name === 'run_command');
if (spec) spec.description += `\n\nThe current working directory is: ${cwd}`;
})
);
return terminals;
})();
// Determine the active terminal (first accessible backend terminal, or user-configured)
const activeTerminal = $terminalServers?.[0] ?? null;
const activeTerminalId = activeTerminal?.id ?? null;
const res = await generateOpenAIChatCompletion(
localStorage.token,
@@ -2166,11 +2156,11 @@
filter_ids: selectedFilterIds.length > 0 ? selectedFilterIds : undefined,
tool_ids: toolIds.length > 0 ? toolIds : undefined,
skill_ids: skillIds.length > 0 ? skillIds : undefined,
terminal_id: activeTerminalId ?? undefined,
tool_servers: [
...($toolServers ?? []).filter(
(server, idx) => toolServerIds.includes(idx) || toolServerIds.includes(server?.id)
),
...terminalServersWithCwd
)
],
features: getFeatures(),
variables: {
+3 -1
View File
@@ -10,6 +10,7 @@
import { onDestroy, onMount, tick, getContext } from 'svelte';
import {
terminalServers,
mobile,
showControls,
showCallOverlay,
@@ -58,7 +59,8 @@
// Tab state for Controls+Files panel
let activeTab: 'controls' | 'files' | 'overview' = savedTab;
$: savedTab = activeTab;
$: hasTerminal = !!($settings?.terminalServers ?? []).find((s) => s.enabled)?.url;
$: hasTerminal = !!($settings?.terminalServers ?? []).find((s) => s.enabled)?.url
|| $terminalServers.length > 0;
$: hasMessages = history?.messages && Object.keys(history.messages).length > 0;
$: if (!hasMessages && activeTab === 'overview') activeTab = 'controls';
+6 -4
View File
@@ -6,7 +6,8 @@
<script lang="ts">
import { toast } from 'svelte-sonner';
import { getContext, onMount, onDestroy, tick } from 'svelte';
import { settings, showFileNavPath } from '$lib/stores';
import { terminalServers, settings, showFileNavPath } from '$lib/stores';
import { WEBUI_API_BASE_URL } from '$lib/constants';
import {
getCwd,
listFiles,
@@ -58,9 +59,10 @@
let showDeleteConfirm = false;
let shiftKey = false;
$: activeTerminal = ($settings?.terminalServers ?? []).find((s) => s.enabled);
$: terminalUrl = activeTerminal?.url ?? '';
$: terminalKey = activeTerminal?.key ?? '';
$: firstTerminal = $terminalServers?.[0] ?? null;
$: activeUserTerminal = ($settings?.terminalServers ?? []).find((s) => s.enabled);
$: terminalUrl = firstTerminal?.url ?? activeUserTerminal?.url ?? '';
$: terminalKey = firstTerminal?.key ?? activeUserTerminal?.key ?? '';
$: configured = !!terminalUrl;
$: breadcrumbs = currentPath