Spaces:
Sleeping
Sleeping
File size: 6,125 Bytes
f2231db 6146397 f2231db 6146397 f2231db 2e9c203 f2231db 9194337 f2231db 2e9c203 f2231db 2e9c203 f2231db 2e9c203 f2231db 6146397 f2231db 6146397 2e9c203 6146397 f2231db 2e9c203 f2231db 2e9c203 f2231db 2e9c203 f2231db 3991883 f2231db 3991883 2e9c203 f2231db 9194337 2e9c203 f2231db 2e9c203 f2231db 2e9c203 f2231db 2e9c203 f2231db 2e9c203 f2231db 2e9c203 f2231db 2e9c203 f2231db 2e9c203 f2231db 2e9c203 f2231db 9194337 8e77934 45e9fba |
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 |
import os
import json
from huggingface_hub import create_repo, list_models, upload_file, constants
from huggingface_hub.utils import build_hf_headers, get_session, hf_raise_for_status
import gradio as gr
from google import genai
from google.genai import types
# --- Globals ---
client = None # Will hold Gemini client
chat = None # Will hold Gemini chat session
# --- System prompt for Gemini ---
system_instruction = (
"You are a helpful assistant that writes, debugs, and pushes code to Hugging Face Spaces. "
"Treat Hugging Face as a sandbox: create spaces, upload code, and debug via function calls. "
"Respond in JSON with {success, data, message}."
)
# --- Function declarations for logs (behind the scenes) ---
get_build_logs_decl = {
"name": "get_build_logs",
"description": "Fetches build logs for a Space",
"parameters": {"type":"object","properties":{"repo_id":{"type":"string"}},"required":["repo_id"]}
}
get_container_logs_decl = {
"name": "get_container_logs",
"description": "Fetches container logs for a Space",
"parameters": {"type":"object","properties":{"repo_id":{"type":"string"}},"required":["repo_id"]}
}
tools = [types.Tool(function_declarations=[get_build_logs_decl, get_container_logs_decl])]
# --- Core Hugging Face functions (unchanged) ---
def _fetch_space_logs_level(repo_id: str, level: str):
jwt_url = f"{constants.ENDPOINT}/api/spaces/{repo_id}/jwt"
r = get_session().get(jwt_url, headers=build_hf_headers())
hf_raise_for_status(r)
jwt = r.json()["token"]
logs_url = f"https://api.hf.space/v1/{repo_id}/logs/{level}"
records = []
with get_session().get(logs_url, headers=build_hf_headers(token=jwt), stream=True) as resp:
hf_raise_for_status(resp)
for raw in resp.iter_lines():
if not raw.startswith(b"data: "): continue
try:
event = json.loads(raw[len(b"data: "):].decode())
records.append({"timestamp": event.get("timestamp"), "message": event.get("data")})
except: pass
return records
# --- Backends for creating space & uploading files ---
def create_space_backend(username: str, hf_token: str, repo_name: str, sdk: str) -> str:
repo_id = f"{username}/{repo_name}"
create_repo(
repo_id=repo_id,
token=hf_token,
exist_ok=True,
repo_type="space",
space_sdk=sdk
)
return repo_id
# --- Chat initialization & handlers ---
def init_chat(repo_name: str, sdk: str, api_key: str, hf_profile: gr.OAuthProfile, hf_token: gr.OAuthToken):
global client, chat
# Validate inputs
if not api_key:
return {"success": False, "data": None, "message": "Missing Gemini API key."}, ""
if hf_profile is None or hf_token is None:
return {"success": False, "data": None, "message": "Please sign in with Hugging Face."}, ""
# Create HF space sandbox
repo_id = create_space_backend(hf_profile.username, hf_token.token, repo_name, sdk)
# Set HF token for log streaming
os.environ["HF_TOKEN"] = hf_token.token
# Init Gemini client and chat
client = genai.Client(api_key=api_key)
chat = client.chats.create(
model="gemini-2.5-flash-preview-04-17",
config=types.GenerateContentConfig(
system_instruction=system_instruction,
tools=tools,
temperature=0
)
)
return {"success": True, "data": None, "message": f"Sandbox ready: {repo_id}"}, repo_id
def chatbot_respond(message: str, history: list, repo_id: str, api_key: str):
global chat, client
if not chat:
# Should not happen if initialized properly
history.append((None, "Error: chat not initialized."))
return history
response = chat.send_message(message)
part = response.candidates[0].content.parts[0]
# Handle function calls
if part.function_call:
fn = part.function_call
args = json.loads(fn.args)
if fn.name == "get_build_logs":
result = _fetch_space_logs_level(repo_id, "build")
else:
result = _fetch_space_logs_level(repo_id, "run")
response2 = chat.send_message("", function_response={fn.name: result})
reply = response2.candidates[0].content.parts[0].text
else:
reply = part.text
history.append((message, reply))
return history
# --- UI: Chatbot with Sidebar for Space Creation ---
with gr.Blocks(title="HF Code Sandbox Chat") as demo:
# Top bar: HF login
with gr.Row():
login_btn = gr.LoginButton(variant="huggingface", label="Sign in with HF")
login_status = gr.Markdown("*Not signed in.*")
login_btn.click(
lambda profile: f"✅ Logged in as {profile.username}" if profile else "*Not signed in.*",
inputs=None, outputs=login_status
)
with gr.Row():
# Sidebar for sandbox setup
with gr.Column(scale=2):
gr.Markdown("### 🏗️ Create New Space Sandbox")
api_key = gr.Textbox(label="Gemini API Key", placeholder="sk-...", type="password")
repo_name = gr.Textbox(label="Space Name", placeholder="my-sandbox")
sdk_selector = gr.Radio(label="SDK", choices=["gradio","streamlit"], value="gradio")
create_btn = gr.Button("Initialize Sandbox")
create_status = gr.JSON(label="Initialization Status")
# Hidden store for repo_id
repo_store = gr.Variable("")
create_btn.click(
init_chat,
inputs=[repo_name, sdk_selector, api_key, login_btn.profile, login_btn.token],
outputs=[create_status, repo_store]
)
# Chat area
with gr.Column(scale=8):
chatbot = gr.Chatbot()
user_input = gr.Textbox(show_label=False, placeholder="Ask the sandbox to write or debug code...")
user_input.submit(
chatbot_respond,
inputs=[user_input, chatbot, repo_store, api_key],
outputs=chatbot
)
if __name__ == "__main__":
demo.launch()
|