import os import gradio as gr from game_config import CLOUD_TICK_SECONDS, HF_MAX_NEW_TOKENS, HF_MODEL_ID from huggingface_hub import InferenceClient from state import ( buy_upgrade, chat_temperature, cloud_tick, new_game, status_lines, toggle_cloud, train_model, unlock_cloud, upgrade_status, ) CSS = """ """ def get_huggingface_response(prompt: str, temperature: float, token: str) -> str: """ Queries Hugging Face using the player's active OAuth token. Uses chat_completion to satisfy the conversational task requirement. """ try: # Securely explicitly initializes InferenceClient with the player's token client = InferenceClient(model=HF_MODEL_ID, token=token) messages = [{"role": "user", "content": prompt}] response = client.chat_completion( messages=messages, max_tokens=HF_MAX_NEW_TOKENS, temperature=max(0.01, temperature), ) return response.choices[0].message.content except Exception as e: return f"[FATAL_ERR] Model Inference Failed: {str(e)}" def render_ui_panes(state: dict) -> tuple[str, str, str]: stats = f"=== SYSTEM STATUS ===\n{status_lines(state)}\n=====================" upg_info = upgrade_status(state) upg_lines = ["=== HARDWARE & ARCHITECTURE MARKETPLACE ==="] for key, info in upg_info.items(): cost_str = f"${info['next_cost']:.0f}" if not info["maxed"] else "MAXED" upg_lines.append( f"{info['icon']} {info['label']} [{info['current_name']}]\n" f" Tier: {info['current_tier']}/{info['max_tier']} | Cost: {cost_str}\n" f" Desc: {info['description']}" ) upg_lines.append("==========================================") log_text = "\n".join(state.get("log", ["[SYS] Cluster Initialized."])) return stats, "\n\n".join(upg_lines), log_text # --- Interface Core Action Mappers --- def handle_init(): state = new_game() stats, upgs, logs = render_ui_panes(state) return state, stats, upgs, logs, gr.update(choices=list(state["upgrades"].keys())) def handle_train(state: dict): new_state, _ = train_model(state) stats, upgs, logs = render_ui_panes(new_state) return new_state, stats, upgs, logs def handle_upgrade(state: dict, upgrade_key: str): if not upgrade_key: return state, gr.update(), gr.update(), gr.update() new_state, _ = buy_upgrade(state, upgrade_key) stats, upgs, logs = render_ui_panes(new_state) return new_state, stats, upgs, logs def handle_cloud_unlock(state: dict): new_state, _ = unlock_cloud(state) stats, upgs, logs = render_ui_panes(new_state) return new_state, stats, upgs, logs def handle_cloud_toggle(state: dict): new_state, _ = toggle_cloud(state) stats, upgs, logs = render_ui_panes(new_state) return new_state, stats, upgs, logs def handle_tick(state: dict): if not state.get("cloud_active", False): return state, gr.update(), gr.update(), gr.update() new_state, revenue = cloud_tick(state) stats, upgs, logs = render_ui_panes(new_state) return new_state, stats, upgs, logs def handle_chat( state: dict, history: list, message: str, profile: gr.OAuthProfile | None, oauth_token: gr.OAuthToken | None, ): if not message.strip(): return history, "" if history is None: history = [] # Block inference if the user isn't authenticated through the UI if oauth_token is None: history.append( [ message, "[SYS_ERR] Access Denied. Please authorize using the 'Sign in with Hugging Face' button.", ] ) return history, "" temp = chat_temperature(state) if temp > 1.4: prompt = f"Produce dynamic fragmented word-salad, glitch texts, and chaotic tokens based loosely on: {message}" else: prompt = message # Execute request using their injected token response = get_huggingface_response(prompt, temp, oauth_token.token) # Reverted to standard tuple arrays to fix TypeError in Chatbot init history.append([message, response]) return history, "" # --- Layout Assembly --- with gr.Blocks(title="AI Training Simulator v2.026") as demo: gr.HTML(CSS) game_state = gr.State() tick_trigger = gr.Button("tick_trigger", visible=False, elem_id="tick_trigger") gr.Markdown("# 📟 THOUSAND TOKEN WOOD // STARTUP TERMINAL") with gr.Column(elem_id="terminal-card"): with gr.Row(): with gr.Column(scale=1): status_pane = gr.Code( label="System Mon", language="markdown", interactive=False ) train_btn = gr.Button("⚡ RUN TRAINING PASS", variant="primary") with gr.Row(): unlock_cloud_btn = gr.Button("🔓 UNLOCK CLOUD") toggle_cloud_btn = gr.Button("⏯️ TOGGLE CLOUD") with gr.Column(scale=1): market_pane = gr.Code( label="Stack Upgrade Hub", language="markdown", interactive=False ) upgrade_dropdown = gr.Dropdown( label="Select Component to Upgrade", choices=[] ) buy_btn = gr.Button("💳 PURCHASE UPGRADE") gr.Markdown("### 📜 Console System Output Logs") log_pane = gr.Textbox( label="", interactive=False, lines=8, elem_id="console-log-area" ) gr.Markdown("### 💬 Live Model Inference Playground") # Injected Native Hugging Face Auth Components with gr.Row(): gr.LoginButton() chatbot = gr.Chatbot(label="Model Output Channel") with gr.Row(): chat_input = gr.Textbox( placeholder="Query model parameter space...", scale=4, show_label=False ) send_btn = gr.Button("📡 INFERENCE", scale=1) # --- Wire UI action flows --- demo.load( handle_init, outputs=[game_state, status_pane, market_pane, log_pane, upgrade_dropdown], ) demo.load( None, js=f""" function() {{ setInterval(() => {{ let btn = document.querySelector('#tick_trigger'); if (btn) btn.click(); }}, {CLOUD_TICK_SECONDS * 1000}); }} """, ) train_btn.click( handle_train, inputs=[game_state], outputs=[game_state, status_pane, market_pane, log_pane], ) buy_btn.click( handle_upgrade, inputs=[game_state, upgrade_dropdown], outputs=[game_state, status_pane, market_pane, log_pane], ) unlock_cloud_btn.click( handle_cloud_unlock, inputs=[game_state], outputs=[game_state, status_pane, market_pane, log_pane], ) toggle_cloud_btn.click( handle_cloud_toggle, inputs=[game_state], outputs=[game_state, status_pane, market_pane, log_pane], ) tick_trigger.click( handle_tick, inputs=[game_state], outputs=[game_state, status_pane, market_pane, log_pane], ) # Gradio handles mapping profile/oauth_token automatically, so we don't put them in the inputs array send_btn.click( handle_chat, inputs=[game_state, chatbot, chat_input], outputs=[chatbot, chat_input], ) chat_input.submit( handle_chat, inputs=[game_state, chatbot, chat_input], outputs=[chatbot, chat_input], ) if __name__ == "__main__": demo.launch()