File size: 4,405 Bytes
afb907c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
f2e3a42
afb907c
f2e3a42
 
 
afb907c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1756609
 
 
 
 
 
 
 
 
 
afb907c
 
 
 
 
 
dca3c38
afb907c
 
 
 
 
 
 
 
 
 
 
 
1756609
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
afb907c
 
 
 
 
 
 
dca3c38
afb907c
 
 
 
 
 
 
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
import os
import httpx
from fastapi import FastAPI, Request
from fastapi.responses import HTMLResponse

app = FastAPI()

HF_TOKEN = os.environ.get("HF_TOKEN", "")


def build_agent_prompt(space_info: dict) -> str:
    space_id = space_info.get("id", "")
    subdomain = space_info.get("subdomain", "")
    description = space_info.get("ai_short_description") or (space_info.get("cardData") or {}).get("short_description")
    base_url = f"https://{subdomain}.hf.space"

    desc_part = f" ({space_id}: {description})" if description else f" ({space_id})"
    return (
        f'This is a Hugging Face Space{desc_part}. '
        f'Immediately fetch its API schema (GET {base_url}/gradio_api/info) to discover available endpoints, '
        f'then ask the user what they want to do. '
        f'Call endpoint: POST {base_url}/gradio_api/call/{{endpoint}} {{"data": [...]}} — '
        f'Poll result: GET {base_url}/gradio_api/call/{{endpoint}}/{{event_id}} — '
        f'auth: Bearer $HF_TOKEN'
    )


@app.get("/proxy/{namespace}/{repo}", response_class=HTMLResponse)
async def proxy_space(namespace: str, repo: str, request: Request):
    space_id = f"{namespace}/{repo}"
    headers = {}
    if HF_TOKEN:
        headers["Authorization"] = f"Bearer {HF_TOKEN}"

    async with httpx.AsyncClient(follow_redirects=True) as client:
        # Fetch space info from API
        api_resp = await client.get(f"https://huggingface.co/api/spaces/{space_id}", headers=headers)
        if api_resp.status_code != 200:
            return HTMLResponse(f"<html><body>Space not found: {space_id}</body></html>", status_code=404)

        space_info = api_resp.json()

        if space_info.get("sdk") != "gradio":
            return HTMLResponse(f"<html><body>Only Gradio spaces are supported. This space uses: {space_info.get('sdk')}</body></html>", status_code=400)

        # Fetch ai_short_description from semantic search
        search_resp = await client.get(
            f"https://huggingface.co/api/spaces/semantic-search?q={space_id}&sdk=gradio",
            headers=headers,
        )
        results = search_resp.json() if search_resp.status_code == 200 else []
        match = next((r for r in results if r.get("id") == space_id), None)
        if match:
            space_info["ai_short_description"] = match.get("ai_short_description")

        # Fetch the actual space page HTML
        page_resp = await client.get(f"https://huggingface.co/spaces/{space_id}", headers=headers)
        html = page_resp.text

        # Build the meta tag
        prompt = build_agent_prompt(space_info)
        meta_tag = f'<meta name="agent-instructions" content="{prompt}">'

        # Inject meta tag after <head> or at the start
        if "<head>" in html:
            html = html.replace("<head>", f"<head>\n{meta_tag}", 1)
        elif "<HEAD>" in html:
            html = html.replace("<HEAD>", f"<HEAD>\n{meta_tag}", 1)
        else:
            html = f"{meta_tag}\n{html}"

    return HTMLResponse(html)


@app.get("/agent-instructions/{namespace}/{repo}")
async def agent_instructions(namespace: str, repo: str):
    space_id = f"{namespace}/{repo}"
    headers = {}
    if HF_TOKEN:
        headers["Authorization"] = f"Bearer {HF_TOKEN}"

    async with httpx.AsyncClient(follow_redirects=True) as client:
        api_resp = await client.get(f"https://huggingface.co/api/spaces/{space_id}", headers=headers)
        if api_resp.status_code != 200:
            return {"error": f"Space not found: {space_id}"}

        space_info = api_resp.json()
        if space_info.get("sdk") != "gradio":
            return {"error": f"Only Gradio spaces supported. This uses: {space_info.get('sdk')}"}

        return {"instructions": build_agent_prompt(space_info)}


@app.get("/", response_class=HTMLResponse)
async def home():
    return HTMLResponse("""
    <html>
    <head><title>Agent Meta Tag Proxy</title></head>
    <body style="font-family: sans-serif; max-width: 600px; margin: 40px auto; padding: 0 20px;">
        <h1>Agent Meta Tag Proxy</h1>
        <p>This Space injects a <code>&lt;meta name="agent-instructions"&gt;</code> tag into Gradio Space pages for AI agent discovery.</p>
        <h3>Usage</h3>
        <pre>/proxy/{namespace}/{repo}</pre>
        <h3>Example</h3>
        <a href="/proxy/mrfakename/Z-Image-Turbo">/proxy/mrfakename/Z-Image-Turbo</a>
    </body>
    </html>
    """)