File size: 6,531 Bytes
e1c010e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
"""
src/ui/layout.py β€” Gradio Blocks layout definition for the VLA Demo.

This module owns *only* the component hierarchy and wiring.
Styling   β†’ src/ui/styles.py
HTML bits β†’ src/ui/components.py
Handlers  β†’ src/ui/handlers.py
Examples  β†’ src/ui/examples.py
"""

import gradio as gr

from src.ui.styles import CUSTOM_CSS
from src.ui.components import HEADER_HTML, FOOTER_HTML
from src.ui.handlers import process_pipeline
from src.ui.examples import get_demo_examples


def create_ui() -> gr.Blocks:
    """
    Build and return the Gradio Blocks interface.

    All sub-modules are imported locally so that this function can be
    called in isolation for testing without triggering heavy model loads.
    """
    demo_examples = get_demo_examples()

    with gr.Blocks(
        title="VLA β€” AI Vision Language Action Pipeline | Codevally",
        theme=gr.themes.Base(
            primary_hue="blue",
            secondary_hue="cyan",
            neutral_hue="slate",
            font=[gr.themes.GoogleFont("Inter"), "system-ui", "sans-serif"],
        ),
        css=CUSTOM_CSS,
    ) as demo:

        # ── Header ────────────────────────────────────────────────────────
        gr.HTML(HEADER_HTML)

        # ── Main layout ───────────────────────────────────────────────────
        with gr.Row(equal_height=False):

            # ── Left: Inputs ───────────────────────────────────────────
            with gr.Column(scale=1, min_width=300):
                gr.Markdown("<div class='cv-section-label'>πŸ“· Input</div>")
                image_input = gr.Image(
                    label="Upload Scene Image",
                    type="numpy",
                    height=280,
                    elem_id="image_upload",
                )
                gr.Markdown(
                    "<div class='cv-section-label' style='margin-top:12px;'>"
                    "πŸ’¬ Natural Language Command</div>"
                )
                command_input = gr.Textbox(
                    label="Command",
                    placeholder=(
                        'e.g. "Pick up the defective board and place it in the red bin"'
                    ),
                    lines=3,
                    show_label=False,
                )
                run_btn = gr.Button(
                    "πŸš€ Run AI Pipeline",
                    variant="primary",
                    size="lg",
                )
                gr.Markdown(
                    "<div class='cv-section-label' style='margin-top:14px;'>"
                    "πŸ“Š Pipeline Status</div>"
                )
                status_output = gr.Markdown(
                    value="*Ready β€” upload a scene image and enter an instruction.*",
                    elem_classes=["status-box"],
                )

            # ── Right: Outputs ─────────────────────────────────────────
            with gr.Column(scale=2):
                with gr.Tabs(elem_id="result_tabs"):

                    with gr.TabItem("πŸ” Detection Results"):
                        gr.Markdown(
                            "_Grounding DINO detects scene objects based on your "
                            "command text β€” no fixed class limitations._"
                        )
                        with gr.Row():
                            detection_image = gr.Image(
                                label="Detected Objects",
                                type="numpy",
                                height=320,
                            )
                            detections_json = gr.Code(
                                label="Detection Data (JSON)",
                                language="json",
                                lines=14,
                            )

                    with gr.TabItem("🎯 Action Plan & Visualization"):
                        gr.Markdown(
                            "_The LLM interprets your command and maps it to detected "
                            "objects, generating step-by-step robotic action instructions._"
                        )
                        with gr.Row():
                            action_image = gr.Image(
                                label="Action Visualization",
                                type="numpy",
                                height=320,
                            )
                            action_plan_md = gr.Markdown(
                                value=(
                                    "*Run the pipeline to see the "
                                    "AI-generated action plan.*"
                                ),
                            )

        # ── Demo examples ──────────────────────────────────────────────────
        if demo_examples:
            gr.Markdown("---")
            gr.Markdown(
                "### πŸ“‚ Try a Demo Scene\n"
                "_Click any example below to load a scene image with a pre-filled "
                "command. These showcase Codevally's VLA pipeline across diverse "
                "industrial and everyday environments._"
            )
            gr.Examples(
                examples=demo_examples,
                inputs=[image_input, command_input],
                label="Demo Scenes",
                examples_per_page=5,
            )

        # ── Footer ────────────────────────────────────────────────────────
        gr.HTML(FOOTER_HTML)

        # ── Event wiring ──────────────────────────────────────────────────
        run_btn.click(
            fn=process_pipeline,
            inputs=[image_input, command_input],
            outputs=[
                detection_image,
                detections_json,
                action_plan_md,
                action_image,
                status_output,
            ],
        )

    return demo