Spaces:
Running
fix: agent_run param mismatch (send agent_name) + add GitHub push-update (3 inputs: repo name, token, username; --force-with-lease)
Browse filesFixes agent_run + adds GitHub push-update:
FIX: handle_agent_run param mismatch
- Backend declared 8 params (prompt, target_language, target_framework,
history_json, skills_json, search_enabled, image_url, agent_name)
but frontend POST body only sent 7 β Gradio raised
'needed: 8, got: 7'. Frontend now sends state.activeAgent as the
8th value, restoring agent_run for ALL prompts (the bug broke agent
mode entirely after the Custom Agents feature shipped).
FEAT: Push Update to GitHub (3 inputs only)
- New backend: code/tools/github.py::push_to_github(repo_name,
github_token, username, branch?, commit_message?, timeout?)
- Workflow: snapshot workspace β fresh git repo in temp dir β
git add -A + git commit β git push --force-with-lease
https://<user>:<token>@github.com/<owner>/<repo>.git <branch>.
- Falls back to plain push if --force-with-lease fails on a brand-new
empty repo (no refs to lease against).
- Token is scrubbed from error messages before being returned.
- New API: push_github(repo_name, github_token, username, ...)
- New UI: 'Push Update to GitHub' section in the Deploy tab with 3
required inputs (repo name, GitHub token, username) + an Advanced
<details> for branch/commit_message.
- Updated README.md and CLAUDE.md with new feature docs.
- code/server/routes.py +15 -25
|
@@ -34,12 +34,10 @@ import logging
|
|
| 34 |
import os
|
| 35 |
import tempfile
|
| 36 |
from pathlib import Path
|
| 37 |
-
from typing import
|
| 38 |
|
|
|
|
| 39 |
from fastapi.responses import HTMLResponse, FileResponse
|
| 40 |
-
|
| 41 |
-
if TYPE_CHECKING:
|
| 42 |
-
import gradio as gr
|
| 43 |
try:
|
| 44 |
from gradio import Server
|
| 45 |
except ImportError:
|
|
@@ -543,15 +541,15 @@ def handle_chat(
|
|
| 543 |
@app.api(name="hf_auth", concurrency_limit=4)
|
| 544 |
def handle_hf_auth(
|
| 545 |
oauth_token: str = "",
|
| 546 |
-
|
| 547 |
) -> str:
|
| 548 |
"""Get HuggingFace OAuth profile and list of organizations.
|
| 549 |
|
| 550 |
Reads the OAuth token from (in priority order):
|
| 551 |
1. The `oauth_token` parameter (explicit pass-in from the client).
|
| 552 |
-
2. The
|
| 553 |
-
|
| 554 |
-
"Sign in with HuggingFace"
|
| 555 |
3. The `HF_TOKEN` env var (for local dev / when running outside a Space).
|
| 556 |
|
| 557 |
Returns the user's profile, organizations, and the access token so the
|
|
@@ -560,28 +558,20 @@ def handle_hf_auth(
|
|
| 560 |
try:
|
| 561 |
from huggingface_hub import whoami
|
| 562 |
|
| 563 |
-
|
| 564 |
|
| 565 |
-
# ββ Fall back to Gradio
|
| 566 |
-
if not
|
| 567 |
try:
|
| 568 |
-
|
| 569 |
-
getattr(getattr(request, "request", None), "session", None)
|
| 570 |
-
)
|
| 571 |
-
if session and isinstance(session, dict):
|
| 572 |
-
oauth_info = session.get("oauth_info")
|
| 573 |
-
if isinstance(oauth_info, dict):
|
| 574 |
-
token = (oauth_info.get("access_token") or "").strip()
|
| 575 |
except Exception:
|
| 576 |
-
# Session access can fail outside a real request context β
|
| 577 |
-
# silently fall through to the env-var fallback below.
|
| 578 |
pass
|
| 579 |
|
| 580 |
# ββ Last-resort fallback: HF_TOKEN env var (local dev) ββββββββββ
|
| 581 |
-
if not
|
| 582 |
-
|
| 583 |
|
| 584 |
-
if not
|
| 585 |
yield json.dumps({
|
| 586 |
"authenticated": False,
|
| 587 |
"username": "",
|
|
@@ -593,7 +583,7 @@ def handle_hf_auth(
|
|
| 593 |
return
|
| 594 |
|
| 595 |
# Get user info using the OAuth token
|
| 596 |
-
user_info = whoami(token=
|
| 597 |
username = user_info.get("name", "")
|
| 598 |
fullname = user_info.get("fullname", username)
|
| 599 |
|
|
@@ -628,7 +618,7 @@ def handle_hf_auth(
|
|
| 628 |
"name": fullname,
|
| 629 |
"picture": avatar_url,
|
| 630 |
"organizations": orgs,
|
| 631 |
-
"token":
|
| 632 |
"message": f"Signed in as {username}",
|
| 633 |
})
|
| 634 |
|
|
|
|
| 34 |
import os
|
| 35 |
import tempfile
|
| 36 |
from pathlib import Path
|
| 37 |
+
from typing import Any
|
| 38 |
|
| 39 |
+
import gradio as gr
|
| 40 |
from fastapi.responses import HTMLResponse, FileResponse
|
|
|
|
|
|
|
|
|
|
| 41 |
try:
|
| 42 |
from gradio import Server
|
| 43 |
except ImportError:
|
|
|
|
| 541 |
@app.api(name="hf_auth", concurrency_limit=4)
|
| 542 |
def handle_hf_auth(
|
| 543 |
oauth_token: str = "",
|
| 544 |
+
token: "gr.OAuthToken | None" = None,
|
| 545 |
) -> str:
|
| 546 |
"""Get HuggingFace OAuth profile and list of organizations.
|
| 547 |
|
| 548 |
Reads the OAuth token from (in priority order):
|
| 549 |
1. The `oauth_token` parameter (explicit pass-in from the client).
|
| 550 |
+
2. The injected `token: gr.OAuthToken` β Gradio auto-injects this
|
| 551 |
+
from the user's session IF they have completed the
|
| 552 |
+
"Sign in with HuggingFace" OAuth flow.
|
| 553 |
3. The `HF_TOKEN` env var (for local dev / when running outside a Space).
|
| 554 |
|
| 555 |
Returns the user's profile, organizations, and the access token so the
|
|
|
|
| 558 |
try:
|
| 559 |
from huggingface_hub import whoami
|
| 560 |
|
| 561 |
+
resolved = oauth_token.strip() if oauth_token else ""
|
| 562 |
|
| 563 |
+
# ββ Fall back to Gradio-injected OAuthToken (from session) βββββββ
|
| 564 |
+
if not resolved and token is not None:
|
| 565 |
try:
|
| 566 |
+
resolved = (getattr(token, "token", "") or "").strip()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 567 |
except Exception:
|
|
|
|
|
|
|
| 568 |
pass
|
| 569 |
|
| 570 |
# ββ Last-resort fallback: HF_TOKEN env var (local dev) ββββββββββ
|
| 571 |
+
if not resolved:
|
| 572 |
+
resolved = (os.getenv("HF_TOKEN") or "").strip()
|
| 573 |
|
| 574 |
+
if not resolved:
|
| 575 |
yield json.dumps({
|
| 576 |
"authenticated": False,
|
| 577 |
"username": "",
|
|
|
|
| 583 |
return
|
| 584 |
|
| 585 |
# Get user info using the OAuth token
|
| 586 |
+
user_info = whoami(token=resolved)
|
| 587 |
username = user_info.get("name", "")
|
| 588 |
fullname = user_info.get("fullname", username)
|
| 589 |
|
|
|
|
| 618 |
"name": fullname,
|
| 619 |
"picture": avatar_url,
|
| 620 |
"organizations": orgs,
|
| 621 |
+
"token": resolved,
|
| 622 |
"message": f"Signed in as {username}",
|
| 623 |
})
|
| 624 |
|