inferoxy-hub / ui_components.py
nazdridoy's picture
refactor(core): rebrand to AI-Inferoxy and update API endpoints
c2e6d7e verified
"""
UI components for AI-Inferoxy AI Hub.
Contains functions to create different sections of the Gradio interface.
"""
import gradio as gr
from utils import (
DEFAULT_CHAT_MODEL, DEFAULT_IMAGE_MODEL, DEFAULT_PROVIDER,
DEFAULT_IMAGE_TO_IMAGE_MODEL,
DEFAULT_TTS_MODEL,
CHAT_CONFIG, IMAGE_CONFIG, IMAGE_PROVIDERS,
TTS_VOICES, TTS_MODEL_CONFIGS,
CHAT_EXAMPLE_PROMPTS, IMAGE_EXAMPLE_PROMPTS, IMAGE_TO_IMAGE_EXAMPLE_PROMPTS, TTS_EXAMPLE_TEXTS, TTS_EXAMPLE_AUDIO_URLS,
DEFAULT_VIDEO_MODEL, VIDEO_EXAMPLE_PROMPTS,
SUGGESTED_CHAT_MODELS, SUGGESTED_IMAGE_MODELS, SUGGESTED_IMAGE_TO_IMAGE_MODELS, SUGGESTED_VIDEO_MODELS
)
def create_chat_tab(handle_chat_submit_fn, handle_chat_retry_fn=None):
"""
Create the chat tab interface.
"""
with gr.Tab("πŸ’¬ Chat Assistant", id="chat"):
# Chat interface at the top - most prominent
chatbot_display = gr.Chatbot(
label="Chat",
type="messages",
height=800,
show_copy_button=True
)
# Chat input
with gr.Row():
chat_input = gr.Textbox(
placeholder="Type your message here...",
label="Message",
scale=4,
container=False
)
chat_submit = gr.Button("Send", variant="primary", scale=1)
chat_stop = gr.Button("⏹ Stop", variant="secondary", scale=0, visible=False)
# Configuration options below the chat
with gr.Row():
with gr.Column(scale=1):
chat_model_name = gr.Dropdown(
choices=SUGGESTED_CHAT_MODELS,
value=DEFAULT_CHAT_MODEL,
label="Model",
info="Select or type any model id",
allow_custom_value=True,
interactive=True
)
chat_provider = gr.Dropdown(
choices=IMAGE_PROVIDERS,
value=DEFAULT_PROVIDER,
label="Provider",
interactive=True
)
chat_system_message = gr.Textbox(
value=CHAT_CONFIG["system_message"],
label="System Message",
lines=2,
placeholder="Define the assistant's personality and behavior..."
)
with gr.Column(scale=1):
chat_max_tokens = gr.Slider(
minimum=1, maximum=4096, value=CHAT_CONFIG["max_tokens"], step=1,
label="Max New Tokens"
)
chat_temperature = gr.Slider(
minimum=0.1, maximum=2.0, value=CHAT_CONFIG["temperature"], step=0.1,
label="Temperature"
)
chat_top_p = gr.Slider(
minimum=0.1, maximum=1.0, value=CHAT_CONFIG["top_p"], step=0.05,
label="Top-p (nucleus sampling)"
)
# Example prompts for chat
with gr.Group():
gr.Markdown("**🌟 Example Prompts**")
gr.Examples(
examples=[[p] for p in CHAT_EXAMPLE_PROMPTS],
inputs=chat_input
)
# Connect chat events (streaming auto-detected from generator function)
# Show stop immediately when sending
chat_submit.click(
fn=lambda: gr.update(visible=True),
inputs=None,
outputs=[chat_stop],
queue=False
)
chat_send_event = chat_submit.click(
fn=handle_chat_submit_fn,
inputs=[chat_input, chatbot_display, chat_system_message, chat_model_name,
chat_provider, chat_max_tokens, chat_temperature, chat_top_p],
outputs=[chatbot_display, chat_input]
)
# Show stop immediately when pressing Enter
chat_input.submit(
fn=lambda: gr.update(visible=True),
inputs=None,
outputs=[chat_stop],
queue=False
)
chat_enter_event = chat_input.submit(
fn=handle_chat_submit_fn,
inputs=[chat_input, chatbot_display, chat_system_message, chat_model_name,
chat_provider, chat_max_tokens, chat_temperature, chat_top_p],
outputs=[chatbot_display, chat_input]
)
# Stop current chat generation
chat_stop.click(
fn=lambda: gr.update(visible=False),
inputs=None,
outputs=[chat_stop],
cancels=[chat_send_event, chat_enter_event],
queue=False
)
# Hide stop after completion of chat events
chat_send_event.then(lambda: gr.update(visible=False), None, [chat_stop], queue=False)
chat_enter_event.then(lambda: gr.update(visible=False), None, [chat_stop], queue=False)
# Enable retry icon and bind handler if provided
if handle_chat_retry_fn is not None:
chatbot_display.retry(
fn=handle_chat_retry_fn,
inputs=[chatbot_display, chat_system_message, chat_model_name,
chat_provider, chat_max_tokens, chat_temperature, chat_top_p],
outputs=chatbot_display
)
def create_image_tab(handle_image_generation_fn):
"""
Create the image generation tab interface.
"""
with gr.Tab("🎨 Image Generator", id="image"):
with gr.Row():
with gr.Column(scale=2):
# Image output
output_image = gr.Image(
label="Generated Image",
type="pil",
height=600,
show_download_button=True
)
status_text = gr.Textbox(
label="Generation Status",
interactive=False,
lines=2
)
with gr.Column(scale=1):
# Model and provider inputs
with gr.Group():
gr.Markdown("**πŸ€– Model & Provider**")
img_model_name = gr.Dropdown(
choices=SUGGESTED_IMAGE_MODELS,
value=DEFAULT_IMAGE_MODEL,
label="Model",
info="Select or type any model id",
allow_custom_value=True,
interactive=True
)
img_provider = gr.Dropdown(
choices=IMAGE_PROVIDERS,
value=DEFAULT_PROVIDER,
label="Provider",
interactive=True
)
# Generation parameters
with gr.Group():
gr.Markdown("**πŸ“ Prompts**")
img_prompt = gr.Textbox(
value=IMAGE_EXAMPLE_PROMPTS[0], # Use first example as default
label="Prompt",
lines=3,
placeholder="Describe the image you want to generate..."
)
img_negative_prompt = gr.Textbox(
value=IMAGE_CONFIG["negative_prompt"],
label="Negative Prompt",
lines=2,
placeholder="Describe what you DON'T want in the image..."
)
with gr.Group():
gr.Markdown("**βš™οΈ Generation Settings**")
with gr.Row():
img_width = gr.Slider(
minimum=256, maximum=2048, value=IMAGE_CONFIG["width"], step=64,
label="Width", info="Must be divisible by 8"
)
img_height = gr.Slider(
minimum=256, maximum=2048, value=IMAGE_CONFIG["height"], step=64,
label="Height", info="Must be divisible by 8"
)
with gr.Row():
img_steps = gr.Slider(
minimum=10, maximum=100, value=IMAGE_CONFIG["num_inference_steps"], step=1,
label="Inference Steps", info="More steps = better quality"
)
img_guidance = gr.Slider(
minimum=1.0, maximum=20.0, value=IMAGE_CONFIG["guidance_scale"], step=0.5,
label="Guidance Scale", info="How closely to follow prompt"
)
img_seed = gr.Slider(
minimum=-1, maximum=999999, value=IMAGE_CONFIG["seed"], step=1,
label="Seed", info="-1 for random"
)
# Generate and Stop buttons
with gr.Row():
generate_btn = gr.Button(
"🎨 Generate Image",
variant="primary",
size="lg",
scale=2
)
stop_generate_btn = gr.Button("⏹ Stop", variant="secondary", visible=False)
# Examples for image generation
create_image_examples(img_prompt)
# Connect image generation events
# Show stop immediately when starting generation
generate_btn.click(
fn=lambda: gr.update(visible=True),
inputs=None,
outputs=[stop_generate_btn],
queue=False
)
gen_event = generate_btn.click(
fn=handle_image_generation_fn,
inputs=[
img_prompt, img_model_name, img_provider, img_negative_prompt,
img_width, img_height, img_steps, img_guidance, img_seed
],
outputs=[output_image, status_text]
)
# Stop current image generation
stop_generate_btn.click(
fn=lambda: gr.update(visible=False),
inputs=None,
outputs=[stop_generate_btn],
cancels=[gen_event],
queue=False
)
# Hide stop after generation completes
gen_event.then(lambda: gr.update(visible=False), None, [stop_generate_btn], queue=False)
def create_image_to_image_tab(handle_image_to_image_generation_fn):
"""
Create the image-to-image tab interface.
"""
with gr.Tab("πŸ–ΌοΈ Image-to-Image", id="image-to-image"):
with gr.Row():
with gr.Column(scale=1):
# Input image
input_image = gr.Image(
label="Input Image",
type="pil",
height=400,
show_download_button=True
)
# Model and provider inputs
with gr.Group():
gr.Markdown("**πŸ€– Model & Provider**")
img2img_model_name = gr.Dropdown(
choices=SUGGESTED_IMAGE_TO_IMAGE_MODELS,
value=DEFAULT_IMAGE_TO_IMAGE_MODEL,
label="Model",
info="Select or type any model id",
allow_custom_value=True,
interactive=True
)
img2img_provider = gr.Dropdown(
choices=IMAGE_PROVIDERS,
value=DEFAULT_PROVIDER,
label="Provider",
interactive=True
)
with gr.Column(scale=1):
# Output image
output_image = gr.Image(
label="Generated Image",
type="pil",
height=400,
show_download_button=True
)
status_text = gr.Textbox(
label="Generation Status",
interactive=False,
lines=2
)
with gr.Column(scale=1):
# Generation parameters
with gr.Group():
gr.Markdown("**πŸ“ Prompts**")
img2img_prompt = gr.Textbox(
value=IMAGE_TO_IMAGE_EXAMPLE_PROMPTS[0], # Use first example as default
label="Prompt",
lines=3,
placeholder="Describe how you want to modify the image..."
)
img2img_negative_prompt = gr.Textbox(
value=IMAGE_CONFIG["negative_prompt"],
label="Negative Prompt",
lines=2,
placeholder="Describe what you DON'T want in the modified image..."
)
with gr.Group():
gr.Markdown("**βš™οΈ Generation Settings**")
with gr.Row():
img2img_steps = gr.Slider(
minimum=10, maximum=100, value=IMAGE_CONFIG["num_inference_steps"], step=1,
label="Inference Steps", info="More steps = better quality"
)
img2img_guidance = gr.Slider(
minimum=1.0, maximum=20.0, value=IMAGE_CONFIG["guidance_scale"], step=0.5,
label="Guidance Scale", info="How closely to follow prompt"
)
img2img_seed = gr.Slider(
minimum=-1, maximum=999999, value=IMAGE_CONFIG["seed"], step=1,
label="Seed", info="-1 for random"
)
# Generate and Stop buttons
with gr.Row():
generate_btn = gr.Button(
"πŸ–ΌοΈ Generate Image-to-Image",
variant="primary",
size="lg",
scale=2
)
stop_generate_btn = gr.Button("⏹ Stop", variant="secondary", visible=False)
# Examples for image-to-image generation
create_image_to_image_examples(img2img_prompt)
# Connect image-to-image generation events
# Show stop immediately when starting generation
generate_btn.click(
fn=lambda: gr.update(visible=True),
inputs=None,
outputs=[stop_generate_btn],
queue=False
)
gen_event = generate_btn.click(
fn=handle_image_to_image_generation_fn,
inputs=[
input_image, img2img_prompt, img2img_model_name, img2img_provider, img2img_negative_prompt,
img2img_steps, img2img_guidance, img2img_seed
],
outputs=[output_image, status_text]
)
# Stop current image-to-image generation
stop_generate_btn.click(
fn=lambda: gr.update(visible=False),
inputs=None,
outputs=[stop_generate_btn],
cancels=[gen_event],
queue=False
)
# Hide stop after generation completes
gen_event.then(lambda: gr.update(visible=False), None, [stop_generate_btn], queue=False)
def create_tts_tab(handle_tts_generation_fn):
"""
Create the text-to-speech tab interface with dynamic model-specific settings.
"""
with gr.Tab("🎀 Text-to-Speech", id="tts"):
with gr.Row():
with gr.Column(scale=2):
# Text input
tts_text = gr.Textbox(
value=TTS_EXAMPLE_TEXTS[0], # Use first example as default
label="Text to Convert",
lines=6,
placeholder="Enter the text you want to convert to speech..."
)
# Audio output
output_audio = gr.Audio(
label="Generated Audio",
type="numpy",
interactive=False,
autoplay=True,
show_download_button=True
)
status_text = gr.Textbox(
label="Generation Status",
interactive=False,
lines=2
)
with gr.Column(scale=1):
# Model and provider inputs
with gr.Group():
gr.Markdown("**πŸ€– Model & Provider**")
tts_model_name = gr.Dropdown(
choices=["hexgrad/Kokoro-82M", "ResembleAI/chatterbox", "nari-labs/Dia-1.6B"],
value=DEFAULT_TTS_MODEL,
label="Model",
info="Select TTS model"
)
tts_provider = gr.Dropdown(
choices=IMAGE_PROVIDERS,
value=DEFAULT_PROVIDER,
label="Provider",
interactive=True
)
# Kokoro-specific settings (initially visible)
with gr.Group(visible=True) as kokoro_settings:
gr.Markdown("**🎀 Kokoro Voice Settings**")
tts_voice = gr.Dropdown(
choices=list(TTS_VOICES.items()),
value="af_bella",
label="Voice",
info="Choose from various English voices"
)
tts_speed = gr.Slider(
minimum=0.5, maximum=2.0, value=1.0, step=0.1,
label="Speed", info="0.5 = slow, 2.0 = fast"
)
# Chatterbox-specific settings (initially hidden)
with gr.Group(visible=False) as chatterbox_settings:
gr.Markdown("**🎭 Chatterbox Style Settings**")
tts_audio_url = gr.Textbox(
value=TTS_EXAMPLE_AUDIO_URLS[0],
label="Reference Audio URL",
placeholder="Enter URL to reference audio file",
info="Audio file to match style and tone"
)
tts_exaggeration = gr.Slider(
minimum=0.0, maximum=1.0, value=0.25, step=0.05,
label="Exaggeration", info="How much to exaggerate the style"
)
tts_temperature = gr.Slider(
minimum=0.0, maximum=1.0, value=0.7, step=0.1,
label="Temperature", info="Creativity level"
)
tts_cfg = gr.Slider(
minimum=0.0, maximum=1.0, value=0.5, step=0.1,
label="CFG", info="Guidance strength"
)
# Generate and Stop buttons
with gr.Row():
generate_btn = gr.Button(
"🎀 Generate Speech",
variant="primary",
size="lg",
scale=2
)
stop_generate_btn = gr.Button("⏹ Stop", variant="secondary", visible=False)
# Examples for TTS generation
create_tts_examples(tts_text)
# Create Chatterbox audio URL examples
create_chatterbox_examples(tts_audio_url)
# Model change handler to show/hide appropriate settings
def on_model_change(model_name):
if model_name == "hexgrad/Kokoro-82M":
return gr.update(visible=True), gr.update(visible=False)
elif model_name == "ResembleAI/chatterbox":
return gr.update(visible=False), gr.update(visible=True)
elif model_name == "nari-labs/Dia-1.6B":
return gr.update(visible=False), gr.update(visible=False)
else:
return gr.update(visible=False), gr.update(visible=False)
# Connect model change event
tts_model_name.change(
fn=on_model_change,
inputs=[tts_model_name],
outputs=[kokoro_settings, chatterbox_settings]
)
# Connect TTS generation events
# Show stop immediately when starting generation
generate_btn.click(
fn=lambda: gr.update(visible=True),
inputs=None,
outputs=[stop_generate_btn],
queue=False
)
gen_event = generate_btn.click(
fn=handle_tts_generation_fn,
inputs=[
tts_text, tts_model_name, tts_provider, tts_voice, tts_speed,
tts_audio_url, tts_exaggeration, tts_temperature, tts_cfg
],
outputs=[output_audio, status_text]
)
# Stop current TTS generation
stop_generate_btn.click(
fn=lambda: gr.update(visible=False),
inputs=None,
outputs=[stop_generate_btn],
cancels=[gen_event],
queue=False
)
# Hide stop after generation completes
gen_event.then(lambda: gr.update(visible=False), None, [stop_generate_btn], queue=False)
def create_video_tab(handle_video_generation_fn):
"""
Create the text-to-video tab interface.
"""
with gr.Tab("🎬 Text-to-Video", id="video"):
with gr.Row():
with gr.Column(scale=2):
# Video output
output_video = gr.Video(
label="Generated Video",
interactive=False,
show_download_button=True,
height=480,
)
status_text = gr.Textbox(
label="Generation Status",
interactive=False,
lines=2
)
with gr.Column(scale=1):
# Model and provider inputs
with gr.Group():
gr.Markdown("**πŸ€– Model & Provider**")
vid_model_name = gr.Dropdown(
choices=SUGGESTED_VIDEO_MODELS,
value=DEFAULT_VIDEO_MODEL,
label="Model",
info="Select or type any model id",
allow_custom_value=True,
interactive=True
)
vid_provider = gr.Dropdown(
choices=IMAGE_PROVIDERS,
value=DEFAULT_PROVIDER,
label="Provider",
interactive=True
)
# Generation parameters
with gr.Group():
gr.Markdown("**πŸ“ Prompt**")
vid_prompt = gr.Textbox(
value=VIDEO_EXAMPLE_PROMPTS[0],
label="Prompt",
lines=3,
placeholder="Describe the video you want to generate..."
)
with gr.Group():
gr.Markdown("**βš™οΈ Generation Settings (optional)**")
with gr.Row():
vid_steps = gr.Slider(
minimum=10, maximum=100, value=20, step=1,
label="Inference Steps"
)
vid_guidance = gr.Slider(
minimum=1.0, maximum=20.0, value=7.5, step=0.5,
label="Guidance Scale"
)
vid_seed = gr.Slider(
minimum=-1, maximum=999999, value=-1, step=1,
label="Seed", info="-1 for random"
)
# Generate and Stop buttons
with gr.Row():
generate_btn = gr.Button(
"🎬 Generate Video",
variant="primary",
size="lg",
scale=2
)
stop_generate_btn = gr.Button("⏹ Stop", variant="secondary", visible=False)
# Examples for video generation
with gr.Group():
gr.Markdown("**🌟 Example Prompts**")
gr.Examples(
examples=[[prompt] for prompt in VIDEO_EXAMPLE_PROMPTS],
inputs=vid_prompt
)
# Connect video generation events
generate_btn.click(
fn=lambda: gr.update(visible=True),
inputs=None,
outputs=[stop_generate_btn],
queue=False
)
gen_event = generate_btn.click(
fn=handle_video_generation_fn,
inputs=[
vid_prompt, vid_model_name, vid_provider,
vid_steps, vid_guidance, vid_seed
],
outputs=[output_video, status_text]
)
# Stop current video generation
stop_generate_btn.click(
fn=lambda: gr.update(visible=False),
inputs=None,
outputs=[stop_generate_btn],
cancels=[gen_event],
queue=False
)
# Hide stop after generation completes
gen_event.then(lambda: gr.update(visible=False), None, [stop_generate_btn], queue=False)
def create_image_to_image_examples(img2img_prompt):
"""Create example prompts for image-to-image generation."""
with gr.Group():
gr.Markdown("**🌟 Example Prompts**")
img2img_examples = gr.Examples(
examples=[[prompt] for prompt in IMAGE_TO_IMAGE_EXAMPLE_PROMPTS],
inputs=img2img_prompt
)
def create_tts_examples(tts_text):
"""Create example texts for text-to-speech generation."""
with gr.Group():
gr.Markdown("**🌟 Example Texts**")
tts_examples = gr.Examples(
examples=[[text] for text in TTS_EXAMPLE_TEXTS],
inputs=tts_text
)
def create_chatterbox_examples(tts_audio_url):
"""Create example audio URLs for Chatterbox TTS."""
with gr.Group():
gr.Markdown("**🎡 Example Reference Audio URLs**")
chatterbox_examples = gr.Examples(
examples=[[url] for url in TTS_EXAMPLE_AUDIO_URLS],
inputs=tts_audio_url
)
def create_image_examples(img_prompt):
"""Create example prompts for image generation."""
with gr.Group():
gr.Markdown("**🌟 Example Prompts**")
img_examples = gr.Examples(
examples=[[prompt] for prompt in IMAGE_EXAMPLE_PROMPTS],
inputs=img_prompt
)
def create_main_header():
"""Create the main header for the application."""
gr.Markdown("""
# πŸš€ AI-Inferoxy AI Hub
A comprehensive AI platform combining chat, image generation, image-to-image, text-to-video, and text-to-speech capabilities with intelligent token management through AI-Inferoxy.
**Features:**
- πŸ’¬ **Smart Chat**: Conversational AI with streaming responses
- 🎨 **Image Generation**: Text-to-image creation with multiple providers
- πŸ–ΌοΈ **Image-to-Image**: Transform and modify existing images with AI
- 🎬 **Text-to-Video**: Generate short videos from text prompts
- 🎀 **Text-to-Speech**: Convert text to natural-sounding speech
- πŸ”„ **Intelligent Token Management**: Automatic token rotation and error handling
- 🌐 **Multi-Provider Support**: Works with HF Inference, Cerebras, Cohere, Groq, Together, Fal.ai, and more
""")
def create_footer():
"""Render a simple footer with helpful links."""
gr.Markdown(
"""
---
### πŸ”— Links
- **Project repo**: https://github.com/nazdridoy/inferoxy-hub
- **AI‑Inferoxy docs**: https://nazdridoy.github.io/ai-inferoxy/
- **License**: https://github.com/nazdridoy/inferoxy-hub/blob/main/LICENSE
"""
)