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 +33 -4
- requirements.txt +4 -1
|
@@ -34,9 +34,12 @@ import logging
|
|
| 34 |
import os
|
| 35 |
import tempfile
|
| 36 |
from pathlib import Path
|
| 37 |
-
from typing import Any
|
| 38 |
|
| 39 |
from fastapi.responses import HTMLResponse, FileResponse
|
|
|
|
|
|
|
|
|
|
| 40 |
try:
|
| 41 |
from gradio import Server
|
| 42 |
except ImportError:
|
|
@@ -540,18 +543,44 @@ def handle_chat(
|
|
| 540 |
@app.api(name="hf_auth", concurrency_limit=4)
|
| 541 |
def handle_hf_auth(
|
| 542 |
oauth_token: str = "",
|
|
|
|
| 543 |
) -> str:
|
| 544 |
"""Get HuggingFace OAuth profile and list of organizations.
|
| 545 |
|
| 546 |
-
|
| 547 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 548 |
"""
|
| 549 |
try:
|
| 550 |
-
import gradio as gr
|
| 551 |
from huggingface_hub import whoami
|
| 552 |
|
| 553 |
token = oauth_token.strip() if oauth_token else ""
|
| 554 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 555 |
if not token:
|
| 556 |
yield json.dumps({
|
| 557 |
"authenticated": False,
|
|
|
|
| 34 |
import os
|
| 35 |
import tempfile
|
| 36 |
from pathlib import Path
|
| 37 |
+
from typing import TYPE_CHECKING, Any
|
| 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 |
@app.api(name="hf_auth", concurrency_limit=4)
|
| 544 |
def handle_hf_auth(
|
| 545 |
oauth_token: str = "",
|
| 546 |
+
request: gr.Request = None,
|
| 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 Gradio session β `request.request.session["oauth_info"]`,
|
| 553 |
+
populated automatically by Gradio after the user clicks
|
| 554 |
+
"Sign in with HuggingFace" and completes the OAuth flow.
|
| 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
|
| 558 |
+
frontend can use it for `push_hf` calls (deploying to user's HF account).
|
| 559 |
"""
|
| 560 |
try:
|
|
|
|
| 561 |
from huggingface_hub import whoami
|
| 562 |
|
| 563 |
token = oauth_token.strip() if oauth_token else ""
|
| 564 |
|
| 565 |
+
# ββ Fall back to Gradio session (populated by /login/huggingface) ββ
|
| 566 |
+
if not token and request is not None:
|
| 567 |
+
try:
|
| 568 |
+
session = getattr(request, "session", None) or (
|
| 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 token:
|
| 582 |
+
token = (os.getenv("HF_TOKEN") or "").strip()
|
| 583 |
+
|
| 584 |
if not token:
|
| 585 |
yield json.dumps({
|
| 586 |
"authenticated": False,
|
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
gradio==6.14.0
|
| 2 |
transformers>=4.45.0
|
| 3 |
torch>=2.1.0
|
| 4 |
accelerate>=0.25.0
|
|
@@ -10,3 +10,6 @@ Pillow>=10.0
|
|
| 10 |
torchvision>=0.16.0
|
| 11 |
# New deps for agent features (most are stdlib in 3.11+)
|
| 12 |
# (No new external deps required β agent/skills/hooks/commands use stdlib only)
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
gradio[oauth]==6.14.0
|
| 2 |
transformers>=4.45.0
|
| 3 |
torch>=2.1.0
|
| 4 |
accelerate>=0.25.0
|
|
|
|
| 10 |
torchvision>=0.16.0
|
| 11 |
# New deps for agent features (most are stdlib in 3.11+)
|
| 12 |
# (No new external deps required β agent/skills/hooks/commands use stdlib only)
|
| 13 |
+
# `gradio[oauth]` extras pull in authlib + itsdangerous for the
|
| 14 |
+
# /login/huggingface + /login/callback OAuth flow. Required for the
|
| 15 |
+
# Sign-in-with-HF button to work in the Deploy tab.
|