File size: 4,776 Bytes
80b7188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
138b29f
80b7188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
c994fd2
 
 
138b29f
 
 
 
80b7188
138b29f
 
 
 
 
 
 
 
80b7188
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
"""

Hugging Face Space: official GenSearcher agent + FireRed-Image-Edit-1.1 generation.



Set PYTHONPATH to include vendor/rllm (see Dockerfile / README).

"""
from __future__ import annotations

import io
import json
import os
from pathlib import Path

import gradio as gr
from PIL import Image

from space_gen import run_sync
from space_health import llm_endpoint_status


def _trajectory_to_markdown(trajectory: list) -> str:
    if not trajectory:
        return "_No messages_"
    parts = []
    for i, m in enumerate(trajectory):
        role = m.get("role", "")
        content = m.get("content", "")
        if isinstance(content, list):
            content = json.dumps(content, ensure_ascii=False)[:8000]
        parts.append(f"### {i + 1}. {role}\n\n```\n{content}\n```\n")
    return "\n".join(parts)


def run_pipeline(

    prompt: str,

    temperature: float,

    top_p: float,

    research_only: bool,

):
    prompt = (prompt or "").strip()
    if not prompt:
        return None, "Enter a non-empty prompt.", "", ""

    try:
        result = run_sync(
            prompt,
            temperature=float(temperature),
            top_p=float(top_p),
            skip_generation=bool(research_only),
        )
    except Exception as e:
        import traceback

        return None, f"**Error**\n\n```\n{e}\n{traceback.format_exc()}\n```", "", ""

    traj_md = _trajectory_to_markdown(result.get("trajectory_messages") or [])
    meta = {
        "termination": result.get("termination"),
        "gen_prompt": result.get("gen_prompt"),
        "used_prompt": result.get("used_prompt"),
        "reference_paths": result.get("reference_paths"),
        "image_error": result.get("image_error"),
    }
    meta_txt = "```json\n" + json.dumps(meta, ensure_ascii=False, indent=2) + "\n```"

    png = result.get("image_png")
    if png:
        img = Image.open(io.BytesIO(png)).convert("RGB")
        return img, meta_txt, traj_md, result.get("gen_prompt") or ""

    return None, meta_txt, traj_md, result.get("gen_prompt") or ""


with gr.Blocks(title="GenSearcher + FireRed") as demo:
    gr.Markdown(
        "## GenSearcher + FireRed-Image-Edit-1.1\n"
        "Runs the **official** GenSearcher search/browse/image-search agent (vLLM), "
        "then generates with **FireRed** via the same `/generate` API as the Qwen edit server.\n\n"
        "**LLM:** Either run Gen-Searcher **in this same Space** (`START_VLLM_GENSEARCHER=1` → vLLM on localhost; "
        "no second Space), **or** set `OPENAI_BASE_URL` to an OpenAI-compatible **`…/v1`** endpoint. "
        "Browse summarization needs `BROWSE_SUMMARY_BASE_URL` when `BROWSE_GENERATE_ENGINE=vllm` (see README).\n\n"
        "**Search / browse (optional keys):** without `SERPER_KEY_ID` and `JINA_API_KEYS`, the agent uses **DuckDuckGo** "
        "for web and image search and **direct HTTP** page fetch for visits. Set those secrets if you prefer Serper + Jina.\n\n"
        "**Connection errors:** On Hugging Face Spaces, `http://127.0.0.1:8002/v1` only works if you run vLLM "
        "in the same container (`START_VLLM_GENSEARCHER=1` + GPU). Otherwise set `OPENAI_BASE_URL` to your **public** inference server."
    )
    status_md = gr.Markdown(llm_endpoint_status())
    refresh_status = gr.Button("Re-check endpoints", size="sm")

    def _refresh():
        return llm_endpoint_status()

    refresh_status.click(fn=_refresh, outputs=status_md)
    demo.load(fn=_refresh, outputs=status_md)
    with gr.Row():
        prompt = gr.Textbox(
            label="Image task / prompt",
            lines=4,
            placeholder="Describe the image you want, including any real-world facts to verify.",
        )
    with gr.Row():
        temperature = gr.Slider(0.0, 1.5, value=0.6, label="Temperature")
        top_p = gr.Slider(0.0, 1.0, value=0.9, label="Top-p")
        research_only = gr.Checkbox(
            label="Research only (no FireRed generation)",
            value=False,
        )
    run_btn = gr.Button("Run", variant="primary")
    with gr.Row():
        out_image = gr.Image(label="Generated image", type="pil")
        out_meta = gr.Markdown(label="Run metadata")
    out_traj = gr.Markdown(label="Trajectory (sanitized)")
    out_gen_prompt = gr.Textbox(label="gen_prompt (from agent)", lines=6)

    run_btn.click(
        fn=run_pipeline,
        inputs=[prompt, temperature, top_p, research_only],
        outputs=[out_image, out_meta, out_traj, out_gen_prompt],
    )

if __name__ == "__main__":
    demo.queue(default_concurrency_limit=1)
    demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("GRADIO_SERVER_PORT", "7860")))