From f0e99d27763e11117e0e994f556f9409b9ce1b99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Kr=C3=BCger?= Date: Sat, 8 Nov 2025 23:15:27 +0100 Subject: [PATCH] revert: remove SFTP integration from AI stack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removed custom Dockerfile and SFTP function integration in favor of the simpler REST API approach (webui-export.py). Changes: - Restored webui service to use official Open WebUI image - Removed custom Dockerfile.webui (paramiko build) - Removed ai/functions/save_to_disk.py SFTP function - Removed SSH key and functions volume mounts The REST API export script (webui-export.py) is a simpler and more flexible solution that doesn't require Docker modifications. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- ai/Dockerfile.webui | 7 -- ai/compose.yaml | 7 +- ai/functions/save_to_disk.py | 195 ----------------------------------- 3 files changed, 1 insertion(+), 208 deletions(-) delete mode 100644 ai/Dockerfile.webui delete mode 100644 ai/functions/save_to_disk.py diff --git a/ai/Dockerfile.webui b/ai/Dockerfile.webui deleted file mode 100644 index ca306f7..0000000 --- a/ai/Dockerfile.webui +++ /dev/null @@ -1,7 +0,0 @@ -FROM ghcr.io/open-webui/open-webui:main - -# Install paramiko for SFTP functionality -RUN pip install --no-cache-dir paramiko - -# Create .ssh directory -RUN mkdir -p /app/.ssh && chmod 700 /app/.ssh diff --git a/ai/compose.yaml b/ai/compose.yaml index acf959d..4df7f7d 100644 --- a/ai/compose.yaml +++ b/ai/compose.yaml @@ -24,10 +24,7 @@ services: # Open WebUI - ChatGPT-like interface for AI models webui: - build: - context: . - dockerfile: ./ai/Dockerfile.webui - image: ${AI_WEBUI_IMAGE:-ai_webui_custom:latest} + image: ${AI_WEBUI_IMAGE:-ghcr.io/open-webui/open-webui:main} container_name: ${AI_COMPOSE_PROJECT_NAME}_webui restart: unless-stopped environment: @@ -66,8 +63,6 @@ services: volumes: - ai_webui_data:/app/backend/data - - ./ai/functions:/app/backend/data/functions:ro - - /root/.ssh/id_rsa:/app/.ssh/id_rsa:ro depends_on: - ai_postgres - litellm diff --git a/ai/functions/save_to_disk.py b/ai/functions/save_to_disk.py deleted file mode 100644 index 58e9c92..0000000 --- a/ai/functions/save_to_disk.py +++ /dev/null @@ -1,195 +0,0 @@ -""" -title: Save Code to Local Disk via SFTP -description: Saves generated code to local filesystem using SFTP -author: Claude -version: 1.0.0 -""" - -import paramiko -import os -from typing import Optional -from pydantic import BaseModel, Field - - -class Tools: - class Valves(BaseModel): - SFTP_HOST: str = Field( - default="vps", - description="SFTP host address" - ) - SFTP_PORT: int = Field( - default=22, - description="SFTP port" - ) - SFTP_USERNAME: str = Field( - default="valknar", - description="SFTP username" - ) - SFTP_BASE_PATH: str = Field( - default="/home/valknar/Projects", - description="Base path for file operations" - ) - SFTP_USE_KEY: bool = Field( - default=True, - description="Use SSH key authentication" - ) - SFTP_KEY_PATH: str = Field( - default="/app/.ssh/id_rsa", - description="Path to SSH private key" - ) - - def __init__(self): - self.valves = self.Valves() - - def save_file( - self, - filepath: str, - content: str, - __user__: dict = {}, - ) -> str: - """ - Save content to a file on the local disk via SFTP. - - :param filepath: Relative path from base directory (e.g. "myproject/main.py") - :param content: File content to save - :return: Success message or error - """ - - try: - # Create SSH client - ssh = paramiko.SSHClient() - ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - - # Connect using SSH key or password - if self.valves.SFTP_USE_KEY: - ssh.connect( - hostname=self.valves.SFTP_HOST, - port=self.valves.SFTP_PORT, - username=self.valves.SFTP_USERNAME, - key_filename=self.valves.SFTP_KEY_PATH, - ) - else: - # For password auth, would need SFTP_PASSWORD in valves - raise ValueError("Password auth not configured. Use SSH key authentication.") - - # Open SFTP session - sftp = ssh.open_sftp() - - # Construct full path - full_path = os.path.join(self.valves.SFTP_BASE_PATH, filepath) - directory = os.path.dirname(full_path) - - # Create directories if they don't exist - try: - sftp.stat(directory) - except FileNotFoundError: - # Create parent directories recursively - dirs = [] - temp_dir = directory - while temp_dir and temp_dir != '/': - try: - sftp.stat(temp_dir) - break - except FileNotFoundError: - dirs.append(temp_dir) - temp_dir = os.path.dirname(temp_dir) - - for dir_path in reversed(dirs): - sftp.mkdir(dir_path) - - # Write file - with sftp.open(full_path, 'w') as f: - f.write(content) - - sftp.close() - ssh.close() - - return f"✅ File saved successfully to: {full_path}" - - except Exception as e: - return f"❌ Error saving file: {str(e)}" - - def read_file( - self, - filepath: str, - __user__: dict = {}, - ) -> str: - """ - Read content from a file on the local disk via SFTP. - - :param filepath: Relative path from base directory (e.g. "myproject/main.py") - :return: File content or error message - """ - - try: - # Create SSH client - ssh = paramiko.SSHClient() - ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - - # Connect using SSH key - ssh.connect( - hostname=self.valves.SFTP_HOST, - port=self.valves.SFTP_PORT, - username=self.valves.SFTP_USERNAME, - key_filename=self.valves.SFTP_KEY_PATH, - ) - - # Open SFTP session - sftp = ssh.open_sftp() - - # Construct full path - full_path = os.path.join(self.valves.SFTP_BASE_PATH, filepath) - - # Read file - with sftp.open(full_path, 'r') as f: - content = f.read() - - sftp.close() - ssh.close() - - return content - - except Exception as e: - return f"❌ Error reading file: {str(e)}" - - def list_files( - self, - directory: str = ".", - __user__: dict = {}, - ) -> str: - """ - List files in a directory on the local disk via SFTP. - - :param directory: Relative directory path from base (e.g. "myproject/") - :return: List of files or error message - """ - - try: - # Create SSH client - ssh = paramiko.SSHClient() - ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) - - # Connect using SSH key - ssh.connect( - hostname=self.valves.SFTP_HOST, - port=self.valves.SFTP_PORT, - username=self.valves.SFTP_USERNAME, - key_filename=self.valves.SFTP_KEY_PATH, - ) - - # Open SFTP session - sftp = ssh.open_sftp() - - # Construct full path - full_path = os.path.join(self.valves.SFTP_BASE_PATH, directory) - - # List files - files = sftp.listdir(full_path) - - sftp.close() - ssh.close() - - return f"📁 Files in {full_path}:\n" + "\n".join(f" - {f}" for f in files) - - except Exception as e: - return f"❌ Error listing files: {str(e)}"