""" ui/components.py β€” reusable Gradio input widgets. Each function returns (component, …) tuples so app.py stays declarative. """ import gradio as gr from config import ( MODELS, DEFAULT_PROMPT, DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE, ) PROMPT_EXAMPLES = [ ["Describe this image in detail."], ["List every object you can see."], ["What is the mood or atmosphere of this image?"], ["What text, if any, appears in this image?"], ["Explain this image to someone who cannot see it."], ["What is unusual or interesting about this image?"], ] def image_upload() -> gr.Image: return gr.Image(type="pil", label="πŸ“· Input Image", height=320) def prompt_box() -> gr.Textbox: return gr.Textbox( value=DEFAULT_PROMPT, label="πŸ’¬ Prompt", lines=3, placeholder="Ask anything about the image…", ) def model_selector() -> gr.Radio: return gr.Radio( choices=list(MODELS.keys()), value=list(MODELS.keys())[0], label="πŸ€– Model", ) def generation_settings() -> tuple[gr.Slider, gr.Slider]: """Returns (max_tokens_slider, temperature_slider).""" with gr.Accordion("βš™οΈ Generation settings", open=False): max_tokens = gr.Slider( 64, 2048, value=DEFAULT_MAX_TOKENS, step=64, label="Max tokens" ) temperature = gr.Slider( 0.0, 1.5, value=DEFAULT_TEMPERATURE, step=0.05, label="Temperature" ) return max_tokens, temperature def api_key_field() -> gr.Textbox: with gr.Accordion("πŸ”‘ API Key", open=False): box = gr.Textbox( label="Your API key (optional)", type="password", lines=1, placeholder="sk-… leave blank to use the free public key", ) gr.Markdown( "A **free public key** is used when this field is blank. \n" "It is shared and rate-limited β€” paste your own key from " "[modelbest.cn](https://modelbest.cn) for unlimited use." ) return box def prompt_examples(prompt_input: gr.Textbox) -> gr.Examples: return gr.Examples( examples=PROMPT_EXAMPLES, inputs=[prompt_input], label="πŸ“ Examples", ) def output_box() -> gr.Textbox: return gr.Textbox( label="πŸ“„ Model Description (streaming)", lines=22, placeholder="Response streams here token-by-token…", ) def info_panel() -> None: gr.Markdown( "---\n" "**API details**\n" "- Endpoint: `https://api.modelbest.cn/v1/chat/completions`\n" "- Protocol: OpenAI-compatible (SSE streaming)\n" "- Auth: Bearer token\n\n" "**Models**\n" "| Model | Params | Best for |\n" "|---|---|---|\n" "| Instruct | 1.3 B | Fast Q&A, descriptions |\n" "| Thinking | 1.3 B | Complex reasoning, OCR |\n" )