R-Kentaren commited on
Commit
19066fd
Β·
verified Β·
1 Parent(s): 0df4996

fix: agent_run param mismatch (send agent_name) + add GitHub push-update (3 inputs: repo name, token, username; --force-with-lease)

Browse files

Fixes 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.

Files changed (2) hide show
  1. code/server/routes.py +33 -4
  2. requirements.txt +4 -1
code/server/routes.py CHANGED
@@ -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
- If oauth_token is provided (from Gradio OAuth), uses it to fetch user info.
547
- Otherwise, returns empty auth info.
 
 
 
 
 
 
 
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,
requirements.txt CHANGED
@@ -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.