Spaces:
Sleeping
Sleeping
# Chat_Workflows.py | |
# Description: UI for Chat Workflows | |
# | |
# Imports | |
import json | |
import logging | |
from pathlib import Path | |
# | |
# External Imports | |
import gradio as gr | |
# | |
from App_Function_Libraries.Gradio_UI.Chat_ui import process_with_llm | |
# | |
############################################################################################################ | |
# | |
# Functions: | |
# Load workflows from a JSON file | |
json_path = Path('./Helper_Scripts/Workflows/Workflows.json') | |
with json_path.open('r') as f: | |
workflows = json.load(f) | |
# FIXME - broken Completely. Doesn't work. | |
def chat_workflows_tab(): | |
with gr.TabItem("Chat Workflows"): | |
gr.Markdown("# Workflows using LLMs") | |
with gr.Row(): | |
workflow_selector = gr.Dropdown(label="Select Workflow", choices=[wf['name'] for wf in workflows]) | |
api_selector = gr.Dropdown( | |
label="Select API Endpoint", | |
choices=["OpenAI", "Anthropic", "Cohere", "Groq", "DeepSeek", "Mistral", "OpenRouter", | |
"Llama.cpp", "Kobold", "Ooba", "Tabbyapi", "VLLM", "ollama", "HuggingFace"], | |
value="OpenAI" | |
) | |
api_key_input = gr.Textbox(label="API Key (optional)", type="password") | |
context_input = gr.Textbox(label="Initial Context (optional)", lines=5) | |
# Create a container for dynamic components | |
with gr.Column() as dynamic_components: | |
prompt_displays = [] | |
user_inputs = [] | |
output_boxes = [] | |
process_buttons = [] | |
regenerate_buttons = [] | |
# Create the maximum number of components needed | |
max_steps = max(len(wf['prompts']) for wf in workflows) | |
for i in range(max_steps): | |
prompt_displays.append(gr.Markdown(visible=False)) | |
user_inputs.append(gr.Textbox(label=f"Your Input", lines=2, visible=False)) | |
output_boxes.append(gr.Textbox(label=f"AI Output", lines=5, visible=False)) | |
with gr.Row(): | |
process_buttons.append(gr.Button(f"Process Step {i + 1}", visible=False)) | |
regenerate_buttons.append(gr.Button(f"🔄 Regenerate", visible=False)) | |
def update_workflow_ui(workflow_name): | |
selected_workflow = next(wf for wf in workflows if wf['name'] == workflow_name) | |
num_prompts = len(selected_workflow['prompts']) | |
prompt_updates = [] | |
input_updates = [] | |
output_updates = [] | |
button_updates = [] | |
regenerate_updates = [] | |
for i in range(max_steps): | |
if i < num_prompts: | |
prompt_updates.append( | |
gr.update(value=f"**Step {i + 1}:** {selected_workflow['prompts'][i]}", visible=True)) | |
input_updates.append(gr.update(value="", visible=True, interactive=(i == 0))) | |
output_updates.append(gr.update(value="", visible=True)) | |
button_updates.append(gr.update(visible=(i == 0))) | |
regenerate_updates.append(gr.update(visible=False)) | |
else: | |
prompt_updates.append(gr.update(visible=False)) | |
input_updates.append(gr.update(visible=False)) | |
output_updates.append(gr.update(visible=False)) | |
button_updates.append(gr.update(visible=False)) | |
regenerate_updates.append(gr.update(visible=False)) | |
return prompt_updates + input_updates + output_updates + button_updates + regenerate_updates | |
def process(context, workflow_name, api_endpoint, api_key, step, *user_inputs): | |
try: | |
selected_workflow = next(wf for wf in workflows if wf['name'] == workflow_name) | |
except StopIteration: | |
# Handle the case where no matching workflow is found | |
error_message = f"No workflow found with name: {workflow_name}" | |
logging.error(error_message) | |
return [gr.update(value=error_message)] * ( | |
len(prompt_displays) + len(user_inputs) + len(output_boxes) + len(process_buttons) + len( | |
regenerate_buttons)) | |
# Ensure we don't go out of bounds | |
if step >= len(selected_workflow['prompts']): | |
error_message = f"Step {step} is out of range for workflow: {workflow_name}" | |
logging.error(error_message) | |
return [gr.update(value=error_message)] * ( | |
len(prompt_displays) + len(user_inputs) + len(output_boxes) + len(process_buttons) + len( | |
regenerate_buttons)) | |
# Build up the context from previous steps | |
full_context = context + "\n\n" | |
for i in range(step + 1): | |
full_context += f"Question: {selected_workflow['prompts'][i]}\n" | |
full_context += f"Answer: {user_inputs[i]}\n" | |
if i < step: | |
full_context += f"AI Output: {output_boxes[i].value}\n\n" | |
try: | |
result = process_with_llm(workflow_name, full_context, selected_workflow['prompts'][step], api_endpoint, | |
api_key) | |
except Exception as e: | |
error_message = f"Error processing with LLM: {str(e)}" | |
logging.error(error_message) | |
result = error_message | |
updates = [] | |
for i in range(max_steps): | |
if i == step: | |
updates.extend([ | |
gr.update(), # Markdown (prompt_displays) | |
gr.update(interactive=False), # Textbox (user_inputs) | |
gr.update(value=result), # Textbox (output_boxes) | |
gr.update(visible=False), # Button (process_buttons) | |
gr.update(visible=True) # Button (regenerate_buttons) | |
]) | |
elif i == step + 1: | |
updates.extend([ | |
gr.update(), # Markdown (prompt_displays) | |
gr.update(interactive=True), # Textbox (user_inputs) | |
gr.update(), # Textbox (output_boxes) | |
gr.update(visible=True), # Button (process_buttons) | |
gr.update(visible=False) # Button (regenerate_buttons) | |
]) | |
elif i > step + 1: | |
updates.extend([ | |
gr.update(), # Markdown (prompt_displays) | |
gr.update(interactive=False), # Textbox (user_inputs) | |
gr.update(), # Textbox (output_boxes) | |
gr.update(visible=False), # Button (process_buttons) | |
gr.update(visible=False) # Button (regenerate_buttons) | |
]) | |
else: | |
updates.extend([ | |
gr.update(), # Markdown (prompt_displays) | |
gr.update(interactive=False), # Textbox (user_inputs) | |
gr.update(), # Textbox (output_boxes) | |
gr.update(visible=False), # Button (process_buttons) | |
gr.update(visible=True) # Button (regenerate_buttons) | |
]) | |
return updates | |
# Set up event handlers | |
workflow_selector.change( | |
update_workflow_ui, | |
inputs=[workflow_selector], | |
outputs=prompt_displays + user_inputs + output_boxes + process_buttons + regenerate_buttons | |
) | |
# Set up process button click events | |
for i, button in enumerate(process_buttons): | |
button.click( | |
fn=lambda context, wf_name, api_endpoint, api_key, *inputs, step=i: process(context, wf_name, | |
api_endpoint, api_key, step, | |
*inputs), | |
inputs=[context_input, workflow_selector, api_selector, api_key_input] + user_inputs, | |
outputs=prompt_displays + user_inputs + output_boxes + process_buttons + regenerate_buttons | |
).then(lambda: gr.update(value=""), outputs=[user_inputs[i]]) | |
# Set up regenerate button click events | |
for i, button in enumerate(regenerate_buttons): | |
button.click( | |
fn=lambda context, wf_name, api_endpoint, api_key, *inputs, step=i: process(context, wf_name, | |
api_endpoint, api_key, step, | |
*inputs), | |
inputs=[context_input, workflow_selector, api_selector, api_key_input] + user_inputs, | |
outputs=prompt_displays + user_inputs + output_boxes + process_buttons + regenerate_buttons | |
) | |
return workflow_selector, api_selector, api_key_input, context_input, dynamic_components | |
# | |
# End of script | |
############################################################################################################ | |