File size: 9,601 Bytes
ef2c267
 
 
 
06e2a4b
 
 
ef2c267
 
06e2a4b
 
 
 
 
ef2c267
06e2a4b
ef2c267
 
06e2a4b
 
 
 
 
 
 
 
 
 
 
 
ef2c267
06e2a4b
 
ef2c267
06e2a4b
 
 
 
 
 
 
 
ef2c267
06e2a4b
 
 
ef2c267
 
06e2a4b
 
 
ef2c267
06e2a4b
 
 
 
 
ef2c267
06e2a4b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ef2c267
06e2a4b
 
 
 
 
 
 
 
 
ef2c267
06e2a4b
 
 
 
 
 
ef2c267
06e2a4b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ef2c267
06e2a4b
 
 
 
 
 
7bffbd9
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
import streamlit as st
import subprocess
import os
import logging
import threading
import time
from huggingface_hub import snapshot_download

# Configure logging
logging.basicConfig(
    filename='supercoder_launcher.log',
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

# Directories
REPO_DIR = os.path.join(os.getcwd(), "SuperCoder")

# Session state initialization
if 'terminal_output' not in st.session_state:
    st.session_state.terminal_output = []
if 'setup_complete' not in st.session_state:
    st.session_state.setup_complete = False
if 'running' not in st.session_state:
    st.session_state.running = False

# ---------- Utility functions ----------
def log_terminal(line: str):
    st.session_state.terminal_output.append(line)
    logging.info(line)

def clear_terminal():
    st.session_state.terminal_output = []

def get_command_output(command: str, cwd: str = None) -> str:
    try:
        result = subprocess.run(
            command, shell=True, cwd=cwd, capture_output=True, text=True, timeout=60
        )
        return result.stdout + "\n" + result.stderr
    except Exception as e:
        return f"Error executing command: {str(e)}"

def run_command_background(command: str, cwd: str = None):
    log_terminal(f"> {command}")
    def target():
        try:
            process = subprocess.Popen(
                command, shell=True, cwd=cwd,
                stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
                text=True, bufsize=1, universal_newlines=True
            )
            for line in process:
                if line:
                    log_terminal(line.rstrip())
            returncode = process.wait()
            log_terminal(f"Process finished with return code: {returncode}")
        except Exception as e:
            log_terminal(f"Exception in background command: {str(e)}")
    threading.Thread(target=target, daemon=True).start()
    st.success("Command started in background. Refresh terminal to see progress.")

# Hugging Face handling (enhanced)
def handle_huggingface(link: str, instruction: str, hf_token: str = None):
    log_terminal(f"Processing Hugging Face link: {link}")
    log_terminal(f"Instruction: {instruction}")
    if "spaces" in link:
        parts = link.split("huggingface.co/spaces/")[-1].strip("/")
        clone_url = f"https://huggingface.co/spaces/{parts}"
        if hf_token:
            clone_url = f"https:{hf_token}@huggingface.co/spaces/{parts}"
        dir_name = parts.split("/")[-1]
        cmd = f"git clone {clone_url} workspaces/{dir_name}"
        run_command_background(cmd, cwd=REPO_DIR)
    elif "datasets" in link or "models" in link:
        repo_id = link.split("huggingface.co/")[-1].strip("/")
        local_dir = os.path.join(REPO_DIR, "models", repo_id.split("/")[-1])
        try:
            path = snapshot_download(
                repo_id=repo_id,
                local_dir=local_dir,
                token=hf_token or None,
                ignore_patterns=["*.bin"] if "small" in instruction.lower() else None
            )
            log_terminal(f"Downloaded {repo_id}{path}")
        except Exception as e:
            log_terminal(f"HF download error: {str(e)}")
    else:
        log_terminal("Unsupported Hugging Face link type.")

# ---------- Main UI ----------
st.set_page_config(page_title="SuperCoder Advanced Launcher", page_icon="🚀", layout="wide")
st.title("🚀 SuperCoder Advanced Launcher")
st.markdown("Full-featured launcher for [TransformerOptimus/SuperCoder](https://github.com/TransformerOptimus/SuperCoder) with Docker Compose, .env config, live logs, preview, and Hugging Face/GitHub integrations.")

tabs = st.tabs(["Setup", "Config", "Run", "Logs & Status", "Preview", "Integrations", "Terminal"])

with tabs[0]:  # Setup
    st.subheader("Repository Management")
    repo_git = os.path.join(REPO_DIR, ".git")
    cloned = os.path.isdir(repo_git)

    if not cloned:
        if st.button("Clone SuperCoder Repository", type="primary"):
            with st.spinner("Cloning repository..."):
                cmd = f"git clone https://github.com/TransformerOptimus/SuperCoder {REPO_DIR}"
                success = subprocess.run(cmd, shell=True, capture_output=True, text=True).returncode == 0
                if success:
                    st.session_state.setup_complete = True
                    st.success("Repository cloned successfully.")
                    st.rerun()
                else:
                    st.error("Clone failed. Check logs.")
    else:
        st.success("✅ Repository cloned")
        st.session_state.setup_complete = True
        if st.button("Update Repository (git pull)"):
            with st.spinner("Pulling latest changes..."):
                run_command_background("git pull", cwd=REPO_DIR)

with tabs[1]:  # Config
    st.subheader(".env Configuration (API keys, etc.)")
    env_path = os.path.join(REPO_DIR, ".env")
    default_env = """OPENAI_API_KEY=sk-...
ANTHROPIC_API_KEY=...
HF_TOKEN=hf_...
# Add other keys as needed
"""
    if os.path.exists(env_path):
        with open(env_path) as f:
            env_content = f.read()
    else:
        env_content = default_env

    new_env = st.text_area(".env content", value=env_content, height=400)
    if st.button("Save .env"):
        try:
            with open(env_path, "w") as f:
                f.write(new_env)
            st.success(".env saved successfully.")
        except Exception as e:
            st.error(f"Save failed: {e}")

with tabs[2]:  # Run
    st.subheader("Docker Compose Controls")
    col1, col2, col3 = st.columns(3)
    with col1:
        if st.button("Start / Rebuild", type="primary", disabled=not st.session_state.setup_complete):
            run_command_background("docker compose up --build -d", cwd=REPO_DIR)
            st.session_state.running = True
    with col2:
        if st.button("Stop"):
            run_command_background("docker compose down", cwd=REPO_DIR)
            st.session_state.running = False
    with col3:
        if st.button("Restart"):
            run_command_background("docker compose restart", cwd=REPO_DIR)

    if st.button("Full Rebuild (down + up --build)"):
        run_command_background("docker compose down && docker compose up --build -d", cwd=REPO_DIR)

with tabs[3]:  # Logs & Status
    st.subheader("Service Status & Logs")
    auto = st.checkbox("Auto-refresh every 8 seconds")
    if auto:
        st.autorefresh(interval=8000, key="logsrefresh")

    c1, c2 = st.columns(2)
    with c1:
        st.markdown("**docker compose ps**")
        status = get_command_output("docker compose ps", cwd=REPO_DIR)
        st.code(status)
    with c2:
        st.markdown("**Recent logs**")
        logs = get_command_output("docker compose logs --tail=1000", cwd=REPO_DIR)
        st.code(logs, language="log")

with tabs[4]:  # Preview
    st.subheader("Live Application Preview")
    if st.session_state.running or "Up" in get_command_output("docker compose ps -q", cwd=REPO_DIR):
        st.components.v1.iframe("http://localhost:3000", height=900, scrolling=True)
    else:
        st.warning("Application not running. Start it in the Run tab first.")

with tabs[5]:  # Integrations
    st.subheader("Hugging Face & GitHub Integrations")
    hf_token = st.text_input("Hugging Face Token (for private repos)", type="password")
    link = st.text_input("Hugging Face or GitHub Link")
    instruction = st.text_area("Instructions (e.g., 'small model only', path hints)")
    if st.button("Process Link"):
        if not link:
            st.error("Provide a link.")
        else:
            if "huggingface.co" in link:
                handle_huggingface(link, instruction, hf_token)
            elif "github.com" in link:
                dir_name = link.split("/")[-1].replace(".git", "")
                cmd = f"git clone {link} workspaces/{dir_name}"
                run_command_background(cmd, cwd=REPO_DIR)
            st.success("Processing started.")

    st.markdown("---")
    st.subheader("Manual HF Model/Dataset Download")
    repo_id = st.text_input("Repo ID (e.g. meta-llama/Llama-3-8B)")
    target_dir = st.text_input("Target subdirectory (relative to SuperCoder)", default="models/custom")
    if st.button("Download Now"):
        full_path = os.path.join(REPO_DIR, target_dir)
        os.makedirs(full_path, exist_ok=True)
        try:
            snapshot_download(repo_id=repo_id, local_dir=full_path, token=hf_token or None)
            st.success(f"Downloaded to {full_path}")
        except Exception as e:
            st.error(str(e))

with tabs[6]:  # Terminal
    st.subheader("Command Output Terminal")
    st.code("\n".join(st.session_state.terminal_output), language="bash")
    col1, col2 = st.columns(2)
    with col1:
        if st.button("Refresh Terminal"):
            st.rerun()
    with col2:
        if st.button("Clear Terminal"):
            clear_terminal()
            st.rerun()

st.sidebar.markdown("### Quick Actions")
if st.sidebar.button("Full Reset (stop + remove repo)"):
    if st.sidebar.checkbox("Confirm dangerous action"):
        run_command_background("docker compose down -v", cwd=REPO_DIR)
        if os.path.exists(REPO_DIR):
            import shutil
            shutil.rmtree(REPO_DIR)
        st.session_state.setup_complete = False
        st.session_state.running = False
        clear_terminal()
        st.success("Reset complete.")

st.sidebar.markdown("---")
st.sidebar.caption(f"Launcher running from: {os.getcwd()}")
st.sidebar.caption("SuperCoder directory: ./SuperCoder")