diff --git a/backend/open_webui/routers/automations.py b/backend/open_webui/routers/automations.py
index 504bc726d..9c532a891 100644
--- a/backend/open_webui/routers/automations.py
+++ b/backend/open_webui/routers/automations.py
@@ -167,15 +167,6 @@ async def create_new_automation(
await check_automation_limits(request, user, form_data.data.rrule, db, is_create=True)
- # Validate terminal server exists if linked
- if form_data.data.terminal and form_data.data.terminal.server_id:
- connections = request.app.state.config.TERMINAL_SERVER_CONNECTIONS or []
- if not any(c.get('id') == form_data.data.terminal.server_id for c in connections):
- raise HTTPException(
- status_code=status.HTTP_400_BAD_REQUEST,
- detail='Terminal server not found',
- )
-
tz = user.timezone
automation = await Automations.insert(user.id, form_data, next_run_ns(form_data.data.rrule, tz=tz), db=db)
return await enrich_automation(automation, db, tz=tz)
@@ -226,15 +217,6 @@ async def update_automation_by_id(
await check_automation_limits(request, user, form_data.data.rrule, db, is_create=False)
- # Validate terminal server exists if linked
- if form_data.data.terminal and form_data.data.terminal.server_id:
- connections = request.app.state.config.TERMINAL_SERVER_CONNECTIONS or []
- if not any(c.get('id') == form_data.data.terminal.server_id for c in connections):
- raise HTTPException(
- status_code=status.HTTP_400_BAD_REQUEST,
- detail='Terminal server not found',
- )
-
tz = user.timezone
updated = await Automations.update_by_id(id, form_data, next_run_ns(form_data.data.rrule, tz=tz), db=db)
return await enrich_automation(updated, db, tz=tz)
diff --git a/backend/open_webui/utils/automations.py b/backend/open_webui/utils/automations.py
index 262430dcf..45b7ba65a 100644
--- a/backend/open_webui/utils/automations.py
+++ b/backend/open_webui/utils/automations.py
@@ -224,6 +224,16 @@ def _resolve_model_filter_ids(app, model_id: str) -> list[str]:
return list(filter_ids) if filter_ids else []
+def _resolve_model_terminal_id(app, model_id: str) -> Optional[str]:
+ """Read model default terminal_id from model config.
+
+ The frontend does this in Chat.svelte (model.info.meta.terminalId).
+ """
+ models = getattr(app.state, 'MODELS', {})
+ model = models.get(model_id, {})
+ return model.get('info', {}).get('meta', {}).get('terminalId') or None
+
+
async def _set_terminal_cwd(app, server_id: str, user, cwd: str, chat_id: str) -> None:
"""Set the working directory on a terminal server via the proxy.
@@ -357,13 +367,8 @@ async def execute_automation(app, automation: AutomationModel) -> None:
features = _resolve_model_features(app, model_id)
filter_ids = _resolve_model_filter_ids(app, model_id)
- # If a terminal is linked, set the CWD before building the payload
- terminal_id = None
- if terminal_config and terminal_config.get('server_id'):
- terminal_id = terminal_config['server_id']
- cwd = terminal_config.get('cwd')
- if cwd:
- await _set_terminal_cwd(app, terminal_id, user, cwd, chat.id)
+ # Resolve terminal from model config
+ terminal_id = _resolve_model_terminal_id(app, model_id)
# Build the same payload the frontend sends to /api/chat/completions
form_data = {
diff --git a/src/lib/components/AutomationModal.svelte b/src/lib/components/AutomationModal.svelte
index c1843f20e..c16265515 100644
--- a/src/lib/components/AutomationModal.svelte
+++ b/src/lib/components/AutomationModal.svelte
@@ -8,7 +8,6 @@
import ScheduleDropdown from '$lib/components/automations/ScheduleDropdown.svelte';
import ModelDropdown from '$lib/components/automations/ModelDropdown.svelte';
- import TerminalDropdown from '$lib/components/automations/TerminalDropdown.svelte';
import {
createAutomation,
@@ -16,7 +15,6 @@
type AutomationForm,
type AutomationResponse
} from '$lib/apis/automations';
- import { getTerminalServers, type TerminalServer } from '$lib/apis/terminal/index';
const i18n = getContext('i18n');
const dispatch = createEventDispatcher();
@@ -31,11 +29,6 @@
let loading = false;
- // Terminal state
- let terminalServers: TerminalServer[] = [];
- let terminalServerId = '';
- let terminalCwd = '';
-
// Schedule dropdown ref
let scheduleDropdown: ScheduleDropdown;
@@ -58,15 +51,7 @@
data: {
prompt: prompt.trim(),
model_id: model_id.trim(),
- rrule: scheduleDropdown.buildRrule(),
- ...(terminalServerId
- ? {
- terminal: {
- server_id: terminalServerId,
- ...(terminalCwd.trim() ? { cwd: terminalCwd.trim() } : {})
- }
- }
- : {})
+ rrule: scheduleDropdown.buildRrule()
},
is_active
};
@@ -90,20 +75,11 @@
};
const init = async () => {
- // Load terminal servers
- try {
- terminalServers = await getTerminalServers(localStorage.token);
- } catch {
- terminalServers = [];
- }
-
if (automation) {
name = automation.name;
prompt = automation.data.prompt;
model_id = automation.data.model_id;
is_active = automation.is_active;
- terminalServerId = automation.data.terminal?.server_id || '';
- terminalCwd = automation.data.terminal?.cwd || '';
if (scheduleDropdown) {
scheduleDropdown.parseRrule(automation.data.rrule);
}
@@ -112,8 +88,6 @@
prompt = '';
model_id = '';
is_active = true;
- terminalServerId = '';
- terminalCwd = '';
}
};
@@ -158,14 +132,6 @@