| """ |
| My Workflow App |
| A workflow application created with MOUSE Workflow builder. |
| Generated by MOUSE Workflow |
| """ |
|
|
| import os |
| import json |
| import gradio as gr |
| import requests |
|
|
| |
| WORKFLOW_DATA = { |
| "nodes": [ |
| { |
| "id": "input_1", |
| "type": "ChatInput", |
| "position": { |
| "x": 100, |
| "y": 200 |
| }, |
| "data": { |
| "label": "User Input", |
| "template": { |
| "input_value": { |
| "value": "AI\uc640 \uba38\uc2e0\ub7ec\ub2dd\uc758 \ucc28\uc774\uc810\uc744 \uc124\uba85\ud574\uc8fc\uc138\uc694." |
| } |
| } |
| } |
| }, |
| { |
| "id": "llm_1", |
| "type": "llmNode", |
| "position": { |
| "x": 400, |
| "y": 200 |
| }, |
| "data": { |
| "label": "VIDraft AI (Gemma)", |
| "template": { |
| "provider": { |
| "value": "VIDraft" |
| }, |
| "model": { |
| "value": "Gemma-3-r1984-27B" |
| }, |
| "temperature": { |
| "value": 0.8 |
| }, |
| "system_prompt": { |
| "value": "\ub2f9\uc2e0\uc740 \uc804\ubb38\uc801\uc774\uace0 \uce5c\uc808\ud55c AI \uad50\uc721\uc790\uc785\ub2c8\ub2e4. \ubcf5\uc7a1\ud55c \uac1c\ub150\uc744 \uc27d\uac8c \uc124\uba85\ud574\uc8fc\uc138\uc694." |
| } |
| } |
| } |
| }, |
| { |
| "id": "output_1", |
| "type": "ChatOutput", |
| "position": { |
| "x": 700, |
| "y": 200 |
| }, |
| "data": { |
| "label": "AI Explanation" |
| } |
| } |
| ], |
| "edges": [ |
| { |
| "id": "e1", |
| "source": "input_1", |
| "target": "llm_1" |
| }, |
| { |
| "id": "e2", |
| "source": "llm_1", |
| "target": "output_1" |
| } |
| ] |
| } |
|
|
| def execute_workflow(*input_values): |
| """Execute the workflow with given inputs""" |
| |
| |
| vidraft_token = os.getenv("FRIENDLI_TOKEN") |
| openai_key = os.getenv("OPENAI_API_KEY") |
| |
| nodes = WORKFLOW_DATA.get("nodes", []) |
| edges = WORKFLOW_DATA.get("edges", []) |
| |
| results = {} |
| |
| |
| input_nodes = [n for n in nodes if n.get("type") in ["ChatInput", "textInput", "Input", "numberInput"]] |
| |
| |
| for i, node in enumerate(input_nodes): |
| if i < len(input_values): |
| results[node["id"]] = input_values[i] |
| |
| |
| for node in nodes: |
| node_id = node.get("id") |
| node_type = node.get("type", "") |
| node_data = node.get("data", {}) |
| template = node_data.get("template", {}) |
| |
| if node_type == "textNode": |
| |
| base_text = template.get("text", {}).get("value", "") |
| connected_inputs = [] |
| |
| for edge in edges: |
| if edge.get("target") == node_id: |
| source_id = edge.get("source") |
| if source_id in results: |
| connected_inputs.append(f"{source_id}: {results[source_id]}") |
| |
| if connected_inputs: |
| results[node_id] = f"{base_text}\n\nInputs:\n" + "\n".join(connected_inputs) |
| else: |
| results[node_id] = base_text |
| |
| elif node_type in ["llmNode", "OpenAIModel", "ChatModel"]: |
| |
| provider = template.get("provider", {}).get("value", "VIDraft") |
| if provider not in ["VIDraft", "OpenAI"]: |
| provider = "VIDraft" |
| temperature = template.get("temperature", {}).get("value", 0.7) |
| system_prompt = template.get("system_prompt", {}).get("value", "") |
| |
| |
| input_text = "" |
| for edge in edges: |
| if edge.get("target") == node_id: |
| source_id = edge.get("source") |
| if source_id in results: |
| input_text = results[source_id] |
| break |
| |
| |
| if provider == "OpenAI" and openai_key: |
| try: |
| from openai import OpenAI |
| client = OpenAI(api_key=openai_key) |
| |
| messages = [] |
| if system_prompt: |
| messages.append({"role": "system", "content": system_prompt}) |
| messages.append({"role": "user", "content": input_text}) |
| |
| response = client.chat.completions.create( |
| model="gpt-4.1-mini", |
| messages=messages, |
| temperature=temperature, |
| max_tokens=1000 |
| ) |
| |
| results[node_id] = response.choices[0].message.content |
| except Exception as e: |
| results[node_id] = f"[OpenAI Error: {str(e)}]" |
| |
| elif provider == "VIDraft" and vidraft_token: |
| try: |
| headers = { |
| "Authorization": f"Bearer {vidraft_token}", |
| "Content-Type": "application/json" |
| } |
| |
| messages = [] |
| if system_prompt: |
| messages.append({"role": "system", "content": system_prompt}) |
| messages.append({"role": "user", "content": input_text}) |
| |
| payload = { |
| "model": "dep89a2fld32mcm", |
| "messages": messages, |
| "max_tokens": 16384, |
| "temperature": temperature, |
| "top_p": 0.8, |
| "stream": False |
| } |
| |
| response = requests.post( |
| "https://api.friendli.ai/dedicated/v1/chat/completions", |
| headers=headers, |
| json=payload, |
| timeout=30 |
| ) |
| |
| if response.status_code == 200: |
| results[node_id] = response.json()["choices"][0]["message"]["content"] |
| else: |
| results[node_id] = f"[VIDraft Error: {response.status_code}]" |
| except Exception as e: |
| results[node_id] = f"[VIDraft Error: {str(e)}]" |
| else: |
| |
| if provider == "OpenAI": |
| results[node_id] = "[OpenAI API key not found. Please set OPENAI_API_KEY in Space secrets]" |
| elif provider == "VIDraft": |
| results[node_id] = "[VIDraft API key not found. Please set FRIENDLI_TOKEN in Space secrets]" |
| else: |
| results[node_id] = f"[No API key found for {provider}. Using simulated response: {input_text[:50]}...]" |
| |
| elif node_type in ["ChatOutput", "textOutput", "Output"]: |
| |
| for edge in edges: |
| if edge.get("target") == node_id: |
| source_id = edge.get("source") |
| if source_id in results: |
| results[node_id] = results[source_id] |
| break |
| |
| |
| output_nodes = [n for n in nodes if n.get("type") in ["ChatOutput", "textOutput", "Output"]] |
| return [results.get(n["id"], "") for n in output_nodes] |
|
|
| |
| with gr.Blocks(title="My Workflow App", theme=gr.themes.Soft()) as demo: |
| gr.Markdown("# My Workflow App") |
| gr.Markdown("A workflow application created with MOUSE Workflow builder.") |
| |
| |
| vidraft_token = os.getenv("FRIENDLI_TOKEN") |
| openai_key = os.getenv("OPENAI_API_KEY") |
| |
| with gr.Accordion("π API Status", open=False): |
| if vidraft_token: |
| gr.Markdown("β
**VIDraft API**: Connected (Gemma-3-r1984-27B)") |
| else: |
| gr.Markdown("β **VIDraft API**: Not configured") |
| |
| if openai_key: |
| gr.Markdown("β
**OpenAI API**: Connected (gpt-4.1-mini)") |
| else: |
| gr.Markdown("β οΈ **OpenAI API**: Not configured (optional)") |
| |
| if not vidraft_token: |
| gr.Markdown(""" |
| **β οΈ Important**: Please add FRIENDLI_TOKEN to Space secrets for the app to work properly. |
| |
| Go to: Space settings β Repository secrets β Add secret |
| """) |
| elif not openai_key: |
| gr.Markdown(""" |
| **π‘ Tip**: The app will work with VIDraft alone. Add OPENAI_API_KEY if you need OpenAI features. |
| """) |
| else: |
| gr.Markdown("**β¨ All APIs configured! Your app is fully functional.**") |
| |
| |
| nodes = WORKFLOW_DATA.get("nodes", []) |
| input_nodes = [n for n in nodes if n.get("type") in ["ChatInput", "textInput", "Input", "numberInput"]] |
| output_nodes = [n for n in nodes if n.get("type") in ["ChatOutput", "textOutput", "Output"]] |
| |
| |
| inputs = [] |
| if input_nodes: |
| gr.Markdown("### π₯ Inputs") |
| for node in input_nodes: |
| label = node.get("data", {}).get("label", node.get("id")) |
| template = node.get("data", {}).get("template", {}) |
| default_value = template.get("input_value", {}).get("value", "") |
| |
| if node.get("type") == "numberInput": |
| inp = gr.Number(label=label, value=float(default_value) if default_value else 0) |
| else: |
| inp = gr.Textbox(label=label, value=default_value, lines=2) |
| inputs.append(inp) |
| |
| |
| btn = gr.Button("π Execute Workflow", variant="primary") |
| |
| |
| outputs = [] |
| if output_nodes: |
| gr.Markdown("### π€ Outputs") |
| for node in output_nodes: |
| label = node.get("data", {}).get("label", node.get("id")) |
| out = gr.Textbox(label=label, interactive=False, lines=3) |
| outputs.append(out) |
| |
| |
| btn.click(fn=execute_workflow, inputs=inputs, outputs=outputs) |
| |
| gr.Markdown("---") |
| gr.Markdown("*Powered by MOUSE Workflow*") |
|
|
| if __name__ == "__main__": |
| demo.launch() |
|
|