Spaces:
Sleeping
Sleeping
File size: 16,177 Bytes
63d9b2f 0ea40d5 2503583 0ea40d5 2503583 f54201d 2503583 43cbde3 2503583 43cbde3 0ea40d5 e80e041 b5a0b96 e2d338a 2503583 43cbde3 2503583 f54201d 0ea40d5 b5a0b96 0ea40d5 642547d 0ea40d5 b5a0b96 2503583 f54201d 0ea40d5 f54201d be9ab33 2503583 be9ab33 e9c1814 2503583 e17517e 2503583 e9c1814 be9ab33 e9c1814 0ea40d5 e2d338a f54201d 0dd3e86 c341524 0dd3e86 c341524 0dd3e86 2503583 4d193ca 2503583 e2d338a 642547d fdc8455 dbe5ee2 fdc8455 b5a0b96 fb0cae8 b5a0b96 0ea40d5 fb0cae8 be9ab33 2503583 bd7c5b9 2503583 bd7c5b9 be9ab33 642547d be9ab33 642547d be9ab33 642547d f54201d 0dd3e86 5fabd70 0dd3e86 5fabd70 0dd3e86 5fabd70 0dd3e86 5fabd70 0dd3e86 5fabd70 0dd3e86 5fabd70 0dd3e86 2503583 642547d e2d338a 2503583 e2d338a 2503583 be9ab33 e2d338a be9ab33 e2d338a be9ab33 e2d338a 2503583 e2d338a be9ab33 e2d338a 0dd3e86 fdc8455 | 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 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 | ο»Ώ# ./app.py
"""
This UI layer sets up a clean initialization screen. It uses a layout state logic gate:
when the page is loaded, it shows a clean login dialog box. If a valid password is sent,
the complete history is queried; if an empty string or incorrect password is submitted,
history retrieval is bypassed entirely, and the main workspace is unlocked securely without global state bleeding.
"""
import gradio as gr
from core_logic import chat_function
from storage import save_chat, load_history, get_chat_content, get_secret_password
from git_agent import manage_github_repo
import os
"""
print("==================================================")
print(f"DEBUG: HF_TOKEN exists? {bool(os.getenv('HF_TOKEN'))}")
print(f"DEBUG: APP_PASSWORD exists? {bool(os.getenv('APP_PASSWORD'))}")
if os.getenv('APP_PASSWORD'):
print(f"DEBUG: APP_PASSWORD length is {len(os.getenv('APP_PASSWORD'))}")
print("==================================================")
"""
with gr.Blocks() as demo:
chat_id_state = gr.State("")
staged_files_state = gr.State([])
# Session state to securely isolate the user's validated password string per browser tab instance
user_session_password = gr.State("")
# ==================== LAYER 1: AUTHENTICATION GATE ====================
with gr.Column(visible=True) as login_layout:
gr.Markdown("## π CoderG Enterprise Access Gate")
gr.Markdown(
"β οΈ **Workspace Notice:** Please leave the password field blank and press the **Unlock Workspace Environment** to proceed directly to the workspace."
)
password_input = gr.Textbox(
label="Security Access Password",
placeholder="Enter password or leave blank for unauthenticated mode...",
type="password"
)
login_btn = gr.Button("Unlock Workspace Environment", variant="primary")
# ==================== LAYER 2: MAIN WORKSPACE ====================
with gr.Row(visible=False) as main_workspace:
# --- Left Panel: Sidebar History ---
with gr.Column(scale=1, variant="secondary"):
gr.Markdown("### π οΈ Silicon Architect")
new_btn = gr.Button("β New Chat", variant="primary")
history_list = gr.Dataset(
components=[gr.Textbox(visible=False)],
label="Recent Conversations",
samples=[],
type="values",
samples_per_page=20
)
# --- Center Panel: Main Core Multimodal Chat ---
with gr.Column(scale=3):
#chatbot = gr.Chatbot(show_label=False, height=700)
active_chat_indicator = gr.Markdown("### π Active Session: *New Conversation*")
chatbot = gr.Chatbot(show_label=False, height=660) # Tweak height slightly to give header room
chat_input = gr.Textbox(
interactive=True,
placeholder="Discuss architecture, paste code blocks, or ask CoderG to produce course documentation...",
show_label=False,
lines=1,
max_lines=10,
scale=8,
submit_btn=False
)
upload_btn = gr.UploadButton(
"π Attach Documents/Images",
file_count="multiple",
file_types=[".png", ".jpg", ".jpeg", ".bmp", ".pdf", ".xlsx", ".xls", ".doc", ".docx", ".md", ".py", ".html", ".css", ".js", ".json", ".csv", ".zip", ".tar.gz", ".log", ".txt"],
scale=2
)
upload_status = gr.Markdown("")
# --- Right Panel: Agentic Control Tower ---
with gr.Column(scale=1, variant="secondary"):
gr.Markdown("### π CoderG Authorization Core")
gr.Markdown("_Authorize code outputs to be compiled into dedicated remote repositories._")
target_repo = gr.Textbox(
label="Target Repository Name",
placeholder="e.g., advanced-python-course",
value="dynamic-course-repo"
)
commit_txt = gr.Textbox(
label="Commit Message",
value="Automated generation via CoderG Agent"
)
staged_files = gr.Textbox(
label="Staged Files (Comma-separated)",
value="COURSE_README.md"
)
approve_btn = gr.Button("Approve & Push to GitHub", variant="primary")
gr.Markdown("#### π Deployment Telemetry Logs")
output_log = gr.Markdown("_Awaiting local environment staging completion..._")
# --- π€ COGNITIVE DREAM CORE ADDITION ---
# 1. Dedicated dynamic UI layer addition to house the Dream mode, reconsolidation telemetry logic
gr.Markdown("---")
gr.Markdown("### π€ Cognitive Dream Core")
dream_btn = gr.Button("π Trigger Autonomous Audit", variant="secondary")
# This hidden box holds the human-in-the-loop verification gate controls
with gr.Group(visible=False) as review_gate_panel:
gr.Markdown("### π¨ Pending Architectural Patch Proposal")
proposal_display = gr.Markdown() # Renders the audit analysis button
with gr.Row():
apply_patch_btn = gr.Button("β
Apply Changes", variant="primary")
discard_patch_btn = gr.Button("β Discard", variant="stop")
dream_status_log = gr.Markdown("_System operating at nominal capacities._")
# --- UI ROUTING HANDLERS ---
def process_login_validation(password_attempt):
"""Step 1: Authenticates strings and updates layout toggles and browser session state."""
target_password = get_secret_password()
clean_attempt = str(password_attempt).strip() if password_attempt is not None else ""
# Explicit Guardrail: Raise an error only if they typed an incorrect password.
if target_password and clean_attempt and clean_attempt != target_password:
raise gr.Error("β Invalid security token entered. Access to environment denied.")
# Returns layout visibility frames alongside the locked-in session password state string
return gr.update(visible=False), gr.update(visible=True), clean_attempt
def populate_history_component(session_password):
"""Step 2: Updates dataset samples based cleanly on isolated session token values."""
# Executes your requested logic: passing session_password down into the storage mechanism
loaded_samples = load_history(user_password=session_password)
return gr.update(samples=loaded_samples)
# --- CORE WORKSPACE LOGIC ---
def handle_file_upload(uploaded_files, current_staged_files):
if not current_staged_files:
current_staged_files = []
for file_obj in uploaded_files:
file_path = file_obj.name if hasattr(file_obj, 'name') else file_obj
if file_path and file_path not in current_staged_files:
current_staged_files.append(file_path)
status_msg = f"π’ **{len(current_staged_files)} file(s) staged successfully and attached to next prompt.**"
return current_staged_files, status_msg
def bot_response(message, history, chat_id):
user_content = message["text"]
clean_history_snapshot = list(history)
history.append({"role": "user", "content": user_content})
history.append({"role": "assistant", "content": ""})
#for partial_resp in chat_function(message, clean_history_snapshot):
# history[-1]["content"] = partial_resp
# yield history
# --- Import and pass client & model down to the function ---
from core_logic import client, model # Adjust this import statement based on where your global client instance lives
for partial_resp in chat_function(message, clean_history_snapshot, client, model):
history[-1]["content"] = partial_resp
yield history
"""
def handle_save(history, chat_id, session_password):
new_id = save_chat(chat_id, history)
# Keeps sidebar refreshes tied strictly to the current session token authentication context
current_list = load_history(user_password=session_password)
if [new_id] not in current_list:
current_list.insert(0, [new_id])
return new_id, gr.update(samples=current_list)
"""
def handle_save(history, chat_id, session_password):
new_id = save_chat(chat_id, history)
# Keeps sidebar refreshes tied strictly to the current session token authentication context
current_list = load_history(user_password=session_password)
if [new_id] not in current_list:
current_list.insert(0, [new_id])
# We return the new_id, the dataset update, AND we update the indicator view
# in case a brand new chat just generated its first true cloud file name.
return new_id, gr.update(samples=current_list), f"### π Active Session: `{new_id}`"
"""
def load_past_chat(selected_list):
chat_id = selected_list[0]
content = get_chat_content(chat_id)
return content, chat_id
"""
def load_past_chat(selected_list):
chat_id = selected_list[0]
content = get_chat_content(chat_id)
# Returns chat log array, updates chat ID tracking state, and updates the header text
return content, chat_id, f"### π Active Session: `{chat_id}`"
def push_authorized(repo_name, commit_msg, files_list):
files = [f.strip() for f in files_list.split(",") if f.strip()]
if not repo_name.strip():
yield "β **Deployment Aborted:** Repository name cannot be empty."
return
yield "β _Connecting to GitHub REST API Engine..._"
result = manage_github_repo(repo_name.strip(), commit_msg, files)
yield f"{result}"
# ==================== BIND COGNITIVE DREAM LIFECYCLES ====================
# A hidden internal string tracking state to isolate the raw proposal across loops
active_proposal_state = gr.State("")
# ==================== COGNITIVE DREAM AGENT FUNCTIONS ====================
def run_background_dream_cycle():
"""
Triggers simulation audit and updates the visibility layers of the UI components safely.
Balanced explicitly to ensure every yield track perfectly populates all 4 output channels.
"""
# STEP 1: Stream Loading States (Now cleanly providing all 4 required positions)
yield (
gr.update(value="β _Cognitive pipeline active: Running simulation audit on core_logic.py..._"),
gr.update(visible=False),
"", # Clears proposal_display layout
"" # Clears active_proposal_state memory buffer
)
# STEP 2: Execute background simulation run
from dream_agent import execute_dream_reflection
raw_proposal = execute_dream_reflection(target_file="core_logic.py")
# Format XML tags into clear, readable Markdown blocks for your review window
user_report_view = raw_proposal.replace("<proposed_patch>", "\n```python\n# === PROPOSED ECOSYSTEM SOURCE PATCH ===\n").replace("</proposed_patch>", "\n```")
# STEP 3: Stream Final Production Payload (All 4 positions accounted for)
yield (
gr.update(value="π’ **Simulation Audit Complete.** Review proposal below before authorizing deployment."),
gr.update(visible=True), # Reveal the gated validation box panel container
user_report_view, # Populate report display markdown layout canvas
raw_proposal # Lock raw text securely inside internal memory state component
)
def commit_authorized_dream_patch(proposal_buffer):
"""Executes patch write operations once explicit user verification is asserted."""
from dream_agent import apply_authorized_patch
result_msg = apply_authorized_patch(proposal_buffer, target_file="core_logic.py")
return gr.update(visible=False), result_msg
def discard_dream_patch():
"""Declines updates cleanly and zeroes out layout states."""
return gr.update(visible=False), "_Proposal safely discarded. Local file state left unchanged._"
# ==================== BIND EVENT LISTENER LIFECYCLES ====================
# Decoupled sequence: Click validates credentials and captures token -> THEN queries data array conditionally
login_btn.click(
fn=process_login_validation,
inputs=[password_input],
outputs=[login_layout, main_workspace, user_session_password]
).then(
fn=populate_history_component,
inputs=[user_session_password],
outputs=[history_list]
)
upload_btn.upload(
fn=handle_file_upload,
inputs=[upload_btn, staged_files_state],
outputs=[staged_files_state, upload_status]
)
def process_submission(message_text, current_staged_files, history, chat_id):
if not message_text.strip() and not current_staged_files:
return history, "", current_staged_files, ""
payload = {"text": message_text, "files": current_staged_files}
for updated_history in bot_response(payload, history, chat_id):
yield updated_history, "", [], ""
chat_input.submit(
fn=process_submission,
inputs=[chat_input, staged_files_state, chatbot, chat_id_state],
outputs=[chatbot, chat_input, staged_files_state, upload_status]
).then(
fn=handle_save,
inputs=[chatbot, chat_id_state, user_session_password],
outputs=[chat_id_state, history_list,
active_chat_indicator] # Updates header text post-save
)
history_list.click(
fn=load_past_chat,
inputs=[history_list],
outputs=[chatbot, chat_id_state,
active_chat_indicator] # Feeds selected chat ID into header
)
"""
new_btn.click(
fn=lambda session_pass: ([], "", [], load_history(user_password=session_pass), "", "_Awaiting local environment staging completion..._"),
inputs=[user_session_password],
outputs=[chatbot, chat_id_state, staged_files_state, history_list, upload_status, output_log]
)
"""
new_btn.click(
fn=lambda session_pass: (
[], "", [], load_history(user_password=session_pass), "",
"_Awaiting local environment staging completion..._", "### π Active Session: *New Conversation*"
),
inputs=[user_session_password],
outputs=[chatbot, chat_id_state, staged_files_state, history_list, upload_status, output_log, active_chat_indicator]
)
approve_btn.click(
fn=push_authorized,
inputs=[target_repo, commit_txt, staged_files],
outputs=[output_log]
)
# Event Assignments
dream_btn.click(
fn=run_background_dream_cycle,
inputs=[],
outputs=[dream_status_log, review_gate_panel, proposal_display, active_proposal_state]
)
apply_patch_btn.click(
fn=commit_authorized_dream_patch,
inputs=[active_proposal_state],
outputs=[review_gate_panel, dream_status_log]
)
discard_patch_btn.click(
fn=discard_dream_patch,
inputs=[],
outputs=[review_gate_panel, dream_status_log]
)
demo.launch(theme=gr.themes.Soft(), css="styles.css") |