Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
@@ -6,9 +6,11 @@ import gradio as gr
|
|
6 |
from google import genai
|
7 |
from google.genai import types
|
8 |
|
9 |
-
# ---
|
10 |
-
client =
|
11 |
-
#
|
|
|
|
|
12 |
system_instruction = (
|
13 |
"You are a helpful assistant that writes, debugs, and pushes code to Hugging Face Spaces. "
|
14 |
"Treat Hugging Face as a sandbox: create spaces, upload code, and debug via function calls. "
|
@@ -19,28 +21,14 @@ system_instruction = (
|
|
19 |
get_build_logs_decl = {
|
20 |
"name": "get_build_logs",
|
21 |
"description": "Fetches build logs for a Space",
|
22 |
-
"parameters": {
|
23 |
-
"type": "object",
|
24 |
-
"properties": {
|
25 |
-
"repo_id": {"type": "string"}
|
26 |
-
},
|
27 |
-
"required": ["repo_id"]
|
28 |
-
}
|
29 |
}
|
30 |
get_container_logs_decl = {
|
31 |
"name": "get_container_logs",
|
32 |
"description": "Fetches container logs for a Space",
|
33 |
-
"parameters": {
|
34 |
-
"type": "object",
|
35 |
-
"properties": {
|
36 |
-
"repo_id": {"type": "string"}
|
37 |
-
},
|
38 |
-
"required": ["repo_id"]
|
39 |
-
}
|
40 |
}
|
41 |
-
tools = [
|
42 |
-
types.Tool(function_declarations=[get_build_logs_decl, get_container_logs_decl])
|
43 |
-
]
|
44 |
|
45 |
# --- Core Hugging Face functions (unchanged) ---
|
46 |
def _fetch_space_logs_level(repo_id: str, level: str):
|
@@ -53,46 +41,39 @@ def _fetch_space_logs_level(repo_id: str, level: str):
|
|
53 |
with get_session().get(logs_url, headers=build_hf_headers(token=jwt), stream=True) as resp:
|
54 |
hf_raise_for_status(resp)
|
55 |
for raw in resp.iter_lines():
|
56 |
-
if not raw.startswith(b"data: "):
|
57 |
-
continue
|
58 |
try:
|
59 |
event = json.loads(raw[len(b"data: "):].decode())
|
60 |
-
records.append({
|
61 |
-
|
62 |
-
"message": event.get("data")
|
63 |
-
})
|
64 |
-
except:
|
65 |
-
pass
|
66 |
return records
|
67 |
|
68 |
-
#
|
69 |
-
def create_space_backend(username,
|
70 |
repo_id = f"{username}/{repo_name}"
|
71 |
create_repo(
|
72 |
repo_id=repo_id,
|
73 |
-
token=
|
74 |
exist_ok=True,
|
75 |
repo_type="space",
|
76 |
space_sdk=sdk
|
77 |
)
|
78 |
return repo_id
|
79 |
|
80 |
-
|
81 |
-
|
82 |
-
|
83 |
-
|
84 |
-
|
85 |
-
|
86 |
-
|
87 |
-
|
88 |
-
|
89 |
-
|
90 |
-
#
|
91 |
-
|
92 |
-
|
93 |
-
|
94 |
-
global chat
|
95 |
-
os.environ["GEMINI_API_KEY"] = api_key
|
96 |
chat = client.chats.create(
|
97 |
model="gemini-2.5-flash-preview-04-17",
|
98 |
config=types.GenerateContentConfig(
|
@@ -101,12 +82,15 @@ def init_chat(repo_id, api_key):
|
|
101 |
temperature=0
|
102 |
)
|
103 |
)
|
104 |
-
return {"success": True, "data": None, "message": f"Sandbox ready: {repo_id}"}
|
|
|
105 |
|
106 |
-
def chatbot_respond(message, history, repo_id, api_key):
|
107 |
-
global chat
|
108 |
-
if chat
|
109 |
-
|
|
|
|
|
110 |
response = chat.send_message(message)
|
111 |
part = response.candidates[0].content.parts[0]
|
112 |
# Handle function calls
|
@@ -126,28 +110,31 @@ def chatbot_respond(message, history, repo_id, api_key):
|
|
126 |
|
127 |
# --- UI: Chatbot with Sidebar for Space Creation ---
|
128 |
with gr.Blocks(title="HF Code Sandbox Chat") as demo:
|
129 |
-
# Top login
|
130 |
with gr.Row():
|
131 |
login_btn = gr.LoginButton(variant="huggingface", label="Sign in with HF")
|
132 |
-
|
133 |
login_btn.click(
|
134 |
lambda profile: f"✅ Logged in as {profile.username}" if profile else "*Not signed in.*",
|
135 |
-
inputs=None,
|
136 |
-
outputs=status
|
137 |
)
|
138 |
|
139 |
with gr.Row():
|
140 |
-
# Sidebar
|
141 |
with gr.Column(scale=2):
|
142 |
gr.Markdown("### 🏗️ Create New Space Sandbox")
|
143 |
api_key = gr.Textbox(label="Gemini API Key", placeholder="sk-...", type="password")
|
144 |
repo_name = gr.Textbox(label="Space Name", placeholder="my-sandbox")
|
145 |
-
sdk_selector = gr.Radio(label="SDK", choices=["gradio",
|
146 |
create_btn = gr.Button("Initialize Sandbox")
|
147 |
-
create_status = gr.JSON(label="
|
148 |
-
|
149 |
-
# hidden store for repo_id
|
150 |
repo_store = gr.Variable("")
|
|
|
|
|
|
|
|
|
|
|
151 |
|
152 |
# Chat area
|
153 |
with gr.Column(scale=8):
|
|
|
6 |
from google import genai
|
7 |
from google.genai import types
|
8 |
|
9 |
+
# --- Globals ---
|
10 |
+
client = None # Will hold Gemini client
|
11 |
+
chat = None # Will hold Gemini chat session
|
12 |
+
|
13 |
+
# --- System prompt for Gemini ---
|
14 |
system_instruction = (
|
15 |
"You are a helpful assistant that writes, debugs, and pushes code to Hugging Face Spaces. "
|
16 |
"Treat Hugging Face as a sandbox: create spaces, upload code, and debug via function calls. "
|
|
|
21 |
get_build_logs_decl = {
|
22 |
"name": "get_build_logs",
|
23 |
"description": "Fetches build logs for a Space",
|
24 |
+
"parameters": {"type":"object","properties":{"repo_id":{"type":"string"}},"required":["repo_id"]}
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
}
|
26 |
get_container_logs_decl = {
|
27 |
"name": "get_container_logs",
|
28 |
"description": "Fetches container logs for a Space",
|
29 |
+
"parameters": {"type":"object","properties":{"repo_id":{"type":"string"}},"required":["repo_id"]}
|
|
|
|
|
|
|
|
|
|
|
|
|
30 |
}
|
31 |
+
tools = [types.Tool(function_declarations=[get_build_logs_decl, get_container_logs_decl])]
|
|
|
|
|
32 |
|
33 |
# --- Core Hugging Face functions (unchanged) ---
|
34 |
def _fetch_space_logs_level(repo_id: str, level: str):
|
|
|
41 |
with get_session().get(logs_url, headers=build_hf_headers(token=jwt), stream=True) as resp:
|
42 |
hf_raise_for_status(resp)
|
43 |
for raw in resp.iter_lines():
|
44 |
+
if not raw.startswith(b"data: "): continue
|
|
|
45 |
try:
|
46 |
event = json.loads(raw[len(b"data: "):].decode())
|
47 |
+
records.append({"timestamp": event.get("timestamp"), "message": event.get("data")})
|
48 |
+
except: pass
|
|
|
|
|
|
|
|
|
49 |
return records
|
50 |
|
51 |
+
# --- Backends for creating space & uploading files ---
|
52 |
+
def create_space_backend(username: str, hf_token: str, repo_name: str, sdk: str) -> str:
|
53 |
repo_id = f"{username}/{repo_name}"
|
54 |
create_repo(
|
55 |
repo_id=repo_id,
|
56 |
+
token=hf_token,
|
57 |
exist_ok=True,
|
58 |
repo_type="space",
|
59 |
space_sdk=sdk
|
60 |
)
|
61 |
return repo_id
|
62 |
|
63 |
+
# --- Chat initialization & handlers ---
|
64 |
+
def init_chat(repo_name: str, sdk: str, api_key: str, hf_profile: gr.OAuthProfile, hf_token: gr.OAuthToken):
|
65 |
+
global client, chat
|
66 |
+
# Validate inputs
|
67 |
+
if not api_key:
|
68 |
+
return {"success": False, "data": None, "message": "Missing Gemini API key."}, ""
|
69 |
+
if hf_profile is None or hf_token is None:
|
70 |
+
return {"success": False, "data": None, "message": "Please sign in with Hugging Face."}, ""
|
71 |
+
# Create HF space sandbox
|
72 |
+
repo_id = create_space_backend(hf_profile.username, hf_token.token, repo_name, sdk)
|
73 |
+
# Set HF token for log streaming
|
74 |
+
os.environ["HF_TOKEN"] = hf_token.token
|
75 |
+
# Init Gemini client and chat
|
76 |
+
client = genai.Client(api_key=api_key)
|
|
|
|
|
77 |
chat = client.chats.create(
|
78 |
model="gemini-2.5-flash-preview-04-17",
|
79 |
config=types.GenerateContentConfig(
|
|
|
82 |
temperature=0
|
83 |
)
|
84 |
)
|
85 |
+
return {"success": True, "data": None, "message": f"Sandbox ready: {repo_id}"}, repo_id
|
86 |
+
|
87 |
|
88 |
+
def chatbot_respond(message: str, history: list, repo_id: str, api_key: str):
|
89 |
+
global chat, client
|
90 |
+
if not chat:
|
91 |
+
# Should not happen if initialized properly
|
92 |
+
history.append((None, "Error: chat not initialized."))
|
93 |
+
return history
|
94 |
response = chat.send_message(message)
|
95 |
part = response.candidates[0].content.parts[0]
|
96 |
# Handle function calls
|
|
|
110 |
|
111 |
# --- UI: Chatbot with Sidebar for Space Creation ---
|
112 |
with gr.Blocks(title="HF Code Sandbox Chat") as demo:
|
113 |
+
# Top bar: HF login
|
114 |
with gr.Row():
|
115 |
login_btn = gr.LoginButton(variant="huggingface", label="Sign in with HF")
|
116 |
+
login_status = gr.Markdown("*Not signed in.*")
|
117 |
login_btn.click(
|
118 |
lambda profile: f"✅ Logged in as {profile.username}" if profile else "*Not signed in.*",
|
119 |
+
inputs=None, outputs=login_status
|
|
|
120 |
)
|
121 |
|
122 |
with gr.Row():
|
123 |
+
# Sidebar for sandbox setup
|
124 |
with gr.Column(scale=2):
|
125 |
gr.Markdown("### 🏗️ Create New Space Sandbox")
|
126 |
api_key = gr.Textbox(label="Gemini API Key", placeholder="sk-...", type="password")
|
127 |
repo_name = gr.Textbox(label="Space Name", placeholder="my-sandbox")
|
128 |
+
sdk_selector = gr.Radio(label="SDK", choices=["gradio","streamlit"], value="gradio")
|
129 |
create_btn = gr.Button("Initialize Sandbox")
|
130 |
+
create_status = gr.JSON(label="Initialization Status")
|
131 |
+
# Hidden store for repo_id
|
|
|
132 |
repo_store = gr.Variable("")
|
133 |
+
create_btn.click(
|
134 |
+
init_chat,
|
135 |
+
inputs=[repo_name, sdk_selector, api_key, login_btn.profile, login_btn.token],
|
136 |
+
outputs=[create_status, repo_store]
|
137 |
+
)
|
138 |
|
139 |
# Chat area
|
140 |
with gr.Column(scale=8):
|