File size: 11,485 Bytes
8a241b0
 
 
 
ea59ef2
 
 
 
 
 
d359a01
620facc
d359a01
 
 
9525f40
331ceb0
d359a01
331ceb0
 
 
 
d359a01
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a241b0
ea59ef2
3e8b0ac
25bcc83
ea59ef2
 
c078d35
3e8b0ac
c078d35
b54fd31
c078d35
 
 
d359a01
c078d35
fc150a7
620facc
c078d35
fc150a7
c078d35
 
fc150a7
c078d35
 
 
 
620facc
c078d35
 
 
 
 
 
 
 
 
 
 
 
 
ea59ef2
3e8b0ac
8a241b0
b54fd31
c078d35
ea59ef2
 
 
 
c078d35
620facc
 
c078d35
b54fd31
ea59ef2
bd77dd8
ea59ef2
 
 
c078d35
 
 
 
 
 
ea59ef2
 
 
c078d35
b54fd31
620facc
c078d35
b54fd31
c078d35
 
3e8b0ac
 
 
 
 
 
c078d35
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3e8b0ac
620facc
 
 
 
 
 
 
 
 
 
 
 
c078d35
 
 
 
25bcc83
 
 
c078d35
25bcc83
8a241b0
b54fd31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8a241b0
620facc
c078d35
b54fd31
 
 
 
 
 
 
8a241b0
b54fd31
 
 
8a241b0
 
 
ea59ef2
b54fd31
ea59ef2
b54fd31
8a241b0
b54fd31
6feae86
a9cbefc
 
 
6feae86
b54fd31
c078d35
ea59ef2
b54fd31
 
ea59ef2
b54fd31
 
 
 
 
c078d35
3e8b0ac
b54fd31
 
 
 
 
3e8b0ac
fc150a7
ea59ef2
 
c078d35
 
0d0c03c
 
 
25bcc83
ea59ef2
a9cbefc
 
 
6feae86
 
 
25bcc83
6feae86
b54fd31
c274a1b
976d2d2
 
 
25bcc83
976d2d2
b54fd31
 
 
 
 
 
 
 
 
 
 
25bcc83
b54fd31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ea59ef2
8a241b0
 
 
 
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
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
import gradio as gr
import threading
import time
from datetime import datetime
from report_generator import (
    generate_csv_report,
    generate_xlsx_report,
    generate_pdf_report,
    generate_diagram_report,
)
import cohere

# Initialize the Cohere client using your provided API key.
COHERE_API_KEY = "ffwtfyfLwqSOtw65psZardfqhUxMr1h7u5vzYotI"
co = cohere.Client(COHERE_API_KEY)

# Define labeled examples for classification as dictionaries.
cohere_examples = [
    {"text": "generate a report on unemployment", "label": "report"},
    {"text": "create a report on market trends", "label": "report"},
    {"text": "generate diagram of sales data", "label": "diagram"},
    {"text": "create a diagram of quarterly revenue", "label": "diagram"}
]

def cohere_parse_command(command):
    """Uses Cohere's classify endpoint to determine the intent of the command."""
    try:
        response = co.classify(
            model="large",
            inputs=[command],
            examples=cohere_examples
        )
        prediction = response.classifications[0].prediction
        return prediction
    except Exception as e:
        print("Cohere classification error, falling back to keyword search:", e)
        lower = command.lower()
        if "diagram" in lower:
            return "diagram"
        elif "report" in lower:
            return "report"
        else:
            return "unknown"

# Global containers for pending tasks and generated files.
task_bucket = []      # Queue of tasks waiting to be processed.
generated_files = []  # Global list of filenames generated.
bucket_lock = threading.Lock()

def process_single_task(task):
    """Process one task with a countdown timer and update its details."""
    print(f"[{datetime.now()}] Processing task: {task['command']}")
    # Simulate processing delay.
    for remaining in range(5, 0, -1):
        task["timer"] = remaining
        time.sleep(1)
    intent = cohere_parse_command(task["command"])
    cmd = task["command"].lower()
    # Pass the entire command as "subject" for dynamic content.
    if intent == "report":
        if "csv" in cmd:
            filename = generate_csv_report(subject=task["command"])
            task["result"] = f"CSV report generated for '{task['command']}'"
        elif "xlsx" in cmd:
            filename = generate_xlsx_report(subject=task["command"])
            task["result"] = f"XLSX report generated for '{task['command']}'"
        else:
            filename = generate_pdf_report(subject=task["command"])
            task["result"] = f"PDF report generated for '{task['command']}'"
    elif intent == "diagram":
        filename = generate_diagram_report()
        task["result"] = f"Diagram generated for '{task['command']}'"
    else:
        filename = None
        task["result"] = f"Unrecognized command: {task['command']}"
    if filename:
        task["file"] = filename
        generated_files.append(filename)
    task["completed_at"] = datetime.now().strftime("%H:%M:%S")
    task["status"] = "Complete"
    task["details"] = f"Task '{task['command']}' processed with result: {task['result']}"
    print(f"[{datetime.now()}] Task completed: {task}")

def background_task_processor():
    """Continuously monitors the task bucket and spawns a new thread per task."""
    while True:
        time.sleep(1)
        task = None
        with bucket_lock:
            if task_bucket:
                task = task_bucket.pop(0)
        if task:
            task["status"] = "In Progress"
            threading.Thread(target=process_single_task, args=(task,), daemon=True).start()

def submit_task(command, current_tasks):
    """Adds a new task when the user clicks Submit (command remains visible)."""
    if command.strip() == "":
        return current_tasks, generated_files, command
    new_task = {
        "command": command,
        "submitted_at": datetime.now().strftime("%H:%M:%S"),
        "timer": "",
        "result": "",
        "file": "",
        "completed_at": "",
        "status": "Pending",
        "details": ""
    }
    with bucket_lock:
        task_bucket.append(new_task)
        current_tasks.append(new_task)
    return current_tasks, generated_files, command

def build_tasks_html(tasks):
    """Builds an HTML table showing task details."""
    html = """
    <style>
      table {width: 100%; border-collapse: collapse; margin: 10px 0; font-family: Arial, sans-serif;}
      th, td {border: 1px solid #ddd; padding: 8px; text-align: left; font-size: 14px;}
      th {background-color: #f2f2f2;}
      .Complete {background-color: #d4edda;}
      .In\\ Progress {background-color: #fff3cd;}
      .Pending {background-color: #f8d7da;}
    </style>
    <table>
      <tr>
        <th>Submitted At</th>
        <th>Command</th>
        <th>Status</th>
        <th>Timer</th>
        <th>Result</th>
        <th>Completed At</th>
        <th>Details</th>
        <th>Done</th>
      </tr>
    """
    for task in tasks:
        status = task.get("status", "Pending")
        timer = task.get("timer", "")
        result = task.get("result", "")
        completed_at = task.get("completed_at", "")
        details = task.get("details", "")
        checkbox = "<input type='checkbox' disabled " + ("checked" if status == "Complete" else "") + ">"
        html += (
            f"<tr class='{status}'>"
            f"<td>{task.get('submitted_at','')}</td>"
            f"<td>{task.get('command','')}</td>"
            f"<td>{status}</td>"
            f"<td>{timer}</td>"
            f"<td>{result}</td>"
            f"<td>{completed_at}</td>"
            f"<td>{details}</td>"
            f"<td>{checkbox}</td>"
            f"</tr>"
        )
    html += "</table>"
    return html

def refresh_ui(tasks, files):
    """Refreshes the UI by rebuilding the task list and updating the files state."""
    # Update files state from the global generated_files list.
    files = generated_files[:]
    tasks_html = build_tasks_html(tasks)
    return tasks, files, tasks_html, files

def update_dropdown(files):
    """Updates the dropdown choices for preview from the list of generated files."""
    return files

def preview_file(file_path):
    """Returns HTML for previewing the file based on its type."""
    if not file_path:
        return "No file selected."
    if file_path.endswith(".png"):
        return f'<img src="{file_path}" style="max-width:100%;">'
    elif file_path.endswith(".pdf"):
        return f'<embed src="{file_path}" type="application/pdf" width="100%" height="600px">'
    elif file_path.endswith(".csv") or file_path.endswith(".xlsx"):
        return f'<a href="{file_path}" target="_blank">Download and view file: {file_path}</a>'
    else:
        return f'<a href="{file_path}" target="_blank">Download file: {file_path}</a>'

def main():
    threading.Thread(target=background_task_processor, daemon=True).start()
    
    with gr.Blocks(css="""
        body {background-color: #121212; font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: #fdfdfd; margin: 0; padding: 0;}
        .gradio-container {max-width: 900px; margin: auto; padding: 20px; background-color: #1e1e1e; border-radius: 8px; box-shadow: 0px 0px 15px rgba(0,0,0,0.5);}
        .title {text-align: center; color: #fdfdfd; margin-bottom: 20px;}
        .section-title {color: #fdfdfd; margin-top: 30px; border-bottom: 2px solid #fdfdfd; padding-bottom: 5px;}
    """) as demo:
        gr.Markdown("<h1 class='title'>Advanced Multi-Task Application</h1>")
        gr.Markdown(
            "Enter a task command below or click one of the sample commands. For example: <i>generate a report on unemployment in the United States in 2024</i>.<br>"
            "Tasks run concurrently and once complete, files will appear in the <b>Completed Downloads</b> section.<br>"
            "You can also preview a completed file in the <b>File Preview</b> section."
        )
        
        with gr.Row():
            with gr.Column(scale=8):
                command_input = gr.Textbox(label="Task Command", placeholder="Type your command here...", lines=2)
            with gr.Column(scale=2):
                submit_btn = gr.Button("Submit", variant="primary")
        
        gr.Markdown("<h3 class='section-title'>Sample Commands</h3>")
        with gr.Row():
            sample1 = gr.Button("Report on US Unemployment 2024")
            sample2 = gr.Button("Diagram of Sales Data")
            sample3 = gr.Button("CSV Report of User Activity")
        
        gr.Markdown("<h3 class='section-title'>Task List</h3>")
        tasks_html_output = gr.HTML(label="Tasks Overview")
        
        gr.Markdown("<h3 class='section-title'>Completed Downloads</h3>")
        file_output = gr.Files(label="Download Files", file_count="multiple")
        
        gr.Markdown("<h3 class='section-title'>File Preview</h3>")
        with gr.Row():
            file_dropdown = gr.Dropdown(choices=[], label="Select File for Preview")
            preview_btn = gr.Button("Preview File")
        preview_output = gr.HTML(label="File Preview")
        
        with gr.Row():
            refresh_btn = gr.Button("Manual Refresh")
            auto_refresh_toggle = gr.Checkbox(value=True, label="Auto Refresh Task List")
        
        tasks_state = gr.State([])
        files_state = gr.State([])
        
        # Submit: add task then immediately refresh UI.
        submit_btn.click(
            submit_task,
            inputs=[command_input, tasks_state],
            outputs=[tasks_state, files_state, command_input]
        ).then(
            refresh_ui,
            inputs=[tasks_state, files_state],
            outputs=[tasks_state, files_state, tasks_html_output, file_output]
        )
        sample1.click(lambda: "generate a report on unemployment in the United States in 2024", None, command_input)
        sample2.click(lambda: "generate diagram of sales data", None, command_input)
        sample3.click(lambda: "generate csv report of user activity", None, command_input)
        refresh_btn.click(
            refresh_ui,
            inputs=[tasks_state, files_state],
            outputs=[tasks_state, files_state, tasks_html_output, file_output]
        )
        # Hidden auto-refresh button.
        auto_refresh_btn = gr.Button("Auto Refresh", visible=False, elem_id="auto_refresh_btn")
        auto_refresh_btn.click(
            refresh_ui,
            inputs=[tasks_state, files_state],
            outputs=[tasks_state, files_state, tasks_html_output, file_output]
        )
        gr.HTML("""
            <script>
              setInterval(function(){
                if(document.getElementById('auto_refresh_toggle').checked){
                  document.getElementById('auto_refresh_btn').click();
                }
              }, 5000);
            </script>
        """)
        auto_refresh_toggle.elem_id = "auto_refresh_toggle"
        
        # Update file dropdown from files state.
        refresh_btn.click(
            update_dropdown,
            inputs=[files_state],
            outputs=[file_dropdown]
        )
        auto_refresh_btn.click(
            update_dropdown,
            inputs=[files_state],
            outputs=[file_dropdown]
        )
        preview_btn.click(
            preview_file,
            inputs=[file_dropdown],
            outputs=[preview_output]
        )
        
    demo.launch(server_name="0.0.0.0", server_port=7860)

if __name__ == "__main__":
    main()