File size: 9,505 Bytes
83c8d2b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
# 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
############################################################################################################