Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -1,34 +1,27 @@
|
|
| 1 |
import gradio as gr
|
|
|
|
| 2 |
import json
|
| 3 |
import boto3
|
| 4 |
-
import uuid
|
| 5 |
import re
|
| 6 |
|
| 7 |
# -----------------------------
|
| 8 |
-
#
|
| 9 |
# -----------------------------
|
| 10 |
|
| 11 |
-
def
|
| 12 |
return {
|
| 13 |
-
"id": str(uuid.uuid4())[:
|
| 14 |
"type": block_type,
|
| 15 |
-
"var": f"{block_type}_{str(uuid.uuid4())[:4]}",
|
| 16 |
"title": block_type.upper(),
|
|
|
|
| 17 |
"value": "",
|
| 18 |
"prompt": "",
|
| 19 |
"system": "",
|
| 20 |
-
"output": ""
|
| 21 |
-
"options": [],
|
| 22 |
-
"min": 0,
|
| 23 |
-
"max": 100,
|
| 24 |
-
"step": 1,
|
| 25 |
}
|
| 26 |
|
| 27 |
def resolve_vars(text, variables):
|
| 28 |
-
|
| 29 |
-
key = match.group(1)
|
| 30 |
-
return variables.get(key, f"{{{{{key}}}}}")
|
| 31 |
-
return re.sub(r"\{\{(\w+)\}\}", repl, text or "")
|
| 32 |
|
| 33 |
# -----------------------------
|
| 34 |
# AI CALL
|
|
@@ -52,110 +45,146 @@ def call_claude(prompt, system):
|
|
| 52 |
return result["content"][0]["text"]
|
| 53 |
|
| 54 |
# -----------------------------
|
| 55 |
-
#
|
| 56 |
# -----------------------------
|
| 57 |
|
| 58 |
-
def
|
| 59 |
variables = {}
|
| 60 |
logs = []
|
| 61 |
|
| 62 |
for b in blocks:
|
| 63 |
try:
|
| 64 |
-
if b["type"] == "text
|
| 65 |
-
variables[b["var"]] = b["value"]
|
| 66 |
-
|
| 67 |
-
elif b["type"] == "select-input":
|
| 68 |
variables[b["var"]] = b["value"]
|
| 69 |
|
| 70 |
-
elif b["type"] == "
|
| 71 |
-
variables[b["var"]] = str(b["value"])
|
| 72 |
-
|
| 73 |
-
elif b["type"] in ["ai-text", "ai-transform"]:
|
| 74 |
prompt = resolve_vars(b["prompt"], variables)
|
| 75 |
-
system = b["system"] or "You are
|
| 76 |
-
output = call_claude(prompt, system)
|
| 77 |
|
|
|
|
| 78 |
b["output"] = output
|
| 79 |
variables[b["var"]] = output
|
| 80 |
-
logs.append(f"✅ {b['title']} ran")
|
| 81 |
|
| 82 |
-
|
| 83 |
-
ref = b.get("ref")
|
| 84 |
-
b["output"] = variables.get(ref, "")
|
| 85 |
|
| 86 |
except Exception as e:
|
| 87 |
logs.append(f"❌ {b['title']} failed: {str(e)}")
|
| 88 |
-
b["output"] = f"Error: {str(e)}"
|
| 89 |
|
| 90 |
return blocks, variables, "\n".join(logs)
|
| 91 |
|
| 92 |
# -----------------------------
|
| 93 |
-
# UI
|
| 94 |
# -----------------------------
|
| 95 |
|
| 96 |
def add_block(blocks, block_type):
|
| 97 |
-
blocks.append(
|
| 98 |
return blocks, blocks
|
| 99 |
|
| 100 |
-
def
|
| 101 |
-
blocks[idx]
|
| 102 |
-
return blocks
|
| 103 |
-
|
| 104 |
-
# -----------------------------
|
| 105 |
-
# UI RENDERER
|
| 106 |
-
# -----------------------------
|
| 107 |
-
|
| 108 |
-
def render_blocks(blocks):
|
| 109 |
-
ui = []
|
| 110 |
-
|
| 111 |
-
for i, b in enumerate(blocks):
|
| 112 |
-
with gr.Group():
|
| 113 |
-
gr.Markdown(f"### {b['title']} ({b['type']})")
|
| 114 |
-
|
| 115 |
-
var = gr.Textbox(value=b["var"], label="Variable")
|
| 116 |
-
val = gr.Textbox(value=b["value"], label="Value")
|
| 117 |
-
|
| 118 |
-
prompt = gr.Textbox(value=b["prompt"], label="Prompt")
|
| 119 |
-
system = gr.Textbox(value=b["system"], label="System Prompt")
|
| 120 |
-
|
| 121 |
-
out = gr.Textbox(value=b.get("output", ""), label="Output")
|
| 122 |
|
| 123 |
-
|
| 124 |
-
|
| 125 |
-
|
| 126 |
-
system.change(lambda v, blocks=blocks, i=i: update_block(blocks, i, "system", v), system, None)
|
| 127 |
-
|
| 128 |
-
ui.append(gr.Markdown("---"))
|
| 129 |
-
|
| 130 |
-
return ui
|
| 131 |
|
| 132 |
# -----------------------------
|
| 133 |
# MAIN UI
|
| 134 |
# -----------------------------
|
| 135 |
|
| 136 |
-
with gr.Blocks(
|
|
|
|
|
|
|
| 137 |
|
| 138 |
blocks_state = gr.State([])
|
|
|
|
| 139 |
|
| 140 |
-
gr.Markdown("# ⚡ Blocksmith
|
| 141 |
|
| 142 |
with gr.Row():
|
| 143 |
-
add_text = gr.Button("➕ Text Input")
|
| 144 |
-
add_ai = gr.Button("➕ AI Generate")
|
| 145 |
-
add_display = gr.Button("➕ Display")
|
| 146 |
-
|
| 147 |
-
blocks_ui = gr.Column()
|
| 148 |
-
|
| 149 |
-
run_btn = gr.Button("▶ Run All")
|
| 150 |
-
output_vars = gr.JSON(label="Variables")
|
| 151 |
-
logs = gr.Textbox(label="Run Logs")
|
| 152 |
-
|
| 153 |
-
# ADD BLOCKS
|
| 154 |
-
add_text.click(lambda b: add_block(b, "text-input"), blocks_state, [blocks_state, blocks_ui])
|
| 155 |
-
add_ai.click(lambda b: add_block(b, "ai-text"), blocks_state, [blocks_state, blocks_ui])
|
| 156 |
-
add_display.click(lambda b: add_block(b, "display"), blocks_state, [blocks_state, blocks_ui])
|
| 157 |
|
| 158 |
-
|
| 159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
|
| 161 |
demo.launch()
|
|
|
|
| 1 |
import gradio as gr
|
| 2 |
+
import uuid
|
| 3 |
import json
|
| 4 |
import boto3
|
|
|
|
| 5 |
import re
|
| 6 |
|
| 7 |
# -----------------------------
|
| 8 |
+
# STATE HELPERS
|
| 9 |
# -----------------------------
|
| 10 |
|
| 11 |
+
def create_block(block_type):
|
| 12 |
return {
|
| 13 |
+
"id": str(uuid.uuid4())[:6],
|
| 14 |
"type": block_type,
|
|
|
|
| 15 |
"title": block_type.upper(),
|
| 16 |
+
"var": f"{block_type}_{str(uuid.uuid4())[:4]}",
|
| 17 |
"value": "",
|
| 18 |
"prompt": "",
|
| 19 |
"system": "",
|
| 20 |
+
"output": ""
|
|
|
|
|
|
|
|
|
|
|
|
|
| 21 |
}
|
| 22 |
|
| 23 |
def resolve_vars(text, variables):
|
| 24 |
+
return re.sub(r"\{\{(\w+)\}\}", lambda m: variables.get(m.group(1), m.group(0)), text or "")
|
|
|
|
|
|
|
|
|
|
| 25 |
|
| 26 |
# -----------------------------
|
| 27 |
# AI CALL
|
|
|
|
| 45 |
return result["content"][0]["text"]
|
| 46 |
|
| 47 |
# -----------------------------
|
| 48 |
+
# CORE ENGINE
|
| 49 |
# -----------------------------
|
| 50 |
|
| 51 |
+
def run_flow(blocks):
|
| 52 |
variables = {}
|
| 53 |
logs = []
|
| 54 |
|
| 55 |
for b in blocks:
|
| 56 |
try:
|
| 57 |
+
if b["type"] == "text":
|
|
|
|
|
|
|
|
|
|
| 58 |
variables[b["var"]] = b["value"]
|
| 59 |
|
| 60 |
+
elif b["type"] == "ai":
|
|
|
|
|
|
|
|
|
|
| 61 |
prompt = resolve_vars(b["prompt"], variables)
|
| 62 |
+
system = b["system"] or "You are helpful"
|
|
|
|
| 63 |
|
| 64 |
+
output = call_claude(prompt, system)
|
| 65 |
b["output"] = output
|
| 66 |
variables[b["var"]] = output
|
|
|
|
| 67 |
|
| 68 |
+
logs.append(f"✅ {b['title']} executed")
|
|
|
|
|
|
|
| 69 |
|
| 70 |
except Exception as e:
|
| 71 |
logs.append(f"❌ {b['title']} failed: {str(e)}")
|
|
|
|
| 72 |
|
| 73 |
return blocks, variables, "\n".join(logs)
|
| 74 |
|
| 75 |
# -----------------------------
|
| 76 |
+
# UI ACTIONS
|
| 77 |
# -----------------------------
|
| 78 |
|
| 79 |
def add_block(blocks, block_type):
|
| 80 |
+
blocks.append(create_block(block_type))
|
| 81 |
return blocks, blocks
|
| 82 |
|
| 83 |
+
def select_block(blocks, idx):
|
| 84 |
+
return blocks, idx, blocks[idx]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 85 |
|
| 86 |
+
def update_block(blocks, idx, data):
|
| 87 |
+
blocks[idx].update(data)
|
| 88 |
+
return blocks
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 89 |
|
| 90 |
# -----------------------------
|
| 91 |
# MAIN UI
|
| 92 |
# -----------------------------
|
| 93 |
|
| 94 |
+
with gr.Blocks(css="""
|
| 95 |
+
body {background-color: #0f172a; color: white;}
|
| 96 |
+
""") as demo:
|
| 97 |
|
| 98 |
blocks_state = gr.State([])
|
| 99 |
+
selected_idx = gr.State(None)
|
| 100 |
|
| 101 |
+
gr.Markdown("# ⚡ Blocksmith AI")
|
| 102 |
|
| 103 |
with gr.Row():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 104 |
|
| 105 |
+
# -----------------------------
|
| 106 |
+
# 🧱 SIDEBAR
|
| 107 |
+
# -----------------------------
|
| 108 |
+
with gr.Column(scale=1):
|
| 109 |
+
gr.Markdown("## 🧩 Blocks")
|
| 110 |
+
|
| 111 |
+
add_text = gr.Button("➕ Text Input")
|
| 112 |
+
add_ai = gr.Button("➕ AI Block")
|
| 113 |
+
|
| 114 |
+
# -----------------------------
|
| 115 |
+
# 🎨 CANVAS
|
| 116 |
+
# -----------------------------
|
| 117 |
+
with gr.Column(scale=2):
|
| 118 |
+
gr.Markdown("## 🧠 Canvas")
|
| 119 |
+
|
| 120 |
+
block_list = gr.Radio(
|
| 121 |
+
choices=[],
|
| 122 |
+
label="Blocks",
|
| 123 |
+
interactive=True
|
| 124 |
+
)
|
| 125 |
+
|
| 126 |
+
# -----------------------------
|
| 127 |
+
# ⚙️ INSPECTOR PANEL
|
| 128 |
+
# -----------------------------
|
| 129 |
+
with gr.Column(scale=2):
|
| 130 |
+
gr.Markdown("## ⚙️ Inspector")
|
| 131 |
+
|
| 132 |
+
var = gr.Textbox(label="Variable")
|
| 133 |
+
value = gr.Textbox(label="Value")
|
| 134 |
+
prompt = gr.Textbox(label="Prompt")
|
| 135 |
+
system = gr.Textbox(label="System")
|
| 136 |
+
output = gr.Textbox(label="Output", interactive=False)
|
| 137 |
+
|
| 138 |
+
# -----------------------------
|
| 139 |
+
# ▶ RUN + LOGS
|
| 140 |
+
# -----------------------------
|
| 141 |
+
run_btn = gr.Button("▶ Run Flow")
|
| 142 |
+
|
| 143 |
+
variables_out = gr.JSON(label="Variables")
|
| 144 |
+
logs = gr.Textbox(label="Logs")
|
| 145 |
+
|
| 146 |
+
# -----------------------------
|
| 147 |
+
# EVENTS
|
| 148 |
+
# -----------------------------
|
| 149 |
+
|
| 150 |
+
# Add blocks
|
| 151 |
+
add_text.click(lambda b: add_block(b, "text"), blocks_state, [blocks_state, block_list])
|
| 152 |
+
add_ai.click(lambda b: add_block(b, "ai"), blocks_state, [blocks_state, block_list])
|
| 153 |
+
|
| 154 |
+
# Update block list display
|
| 155 |
+
def refresh_list(blocks):
|
| 156 |
+
return [f"{i}: {b['title']}" for i, b in enumerate(blocks)]
|
| 157 |
+
|
| 158 |
+
blocks_state.change(refresh_list, blocks_state, block_list)
|
| 159 |
+
|
| 160 |
+
# Select block
|
| 161 |
+
def load_block(blocks, idx):
|
| 162 |
+
if idx is None:
|
| 163 |
+
return "", "", "", "", ""
|
| 164 |
+
b = blocks[int(idx.split(":")[0])]
|
| 165 |
+
return b["var"], b["value"], b["prompt"], b["system"], b["output"]
|
| 166 |
+
|
| 167 |
+
block_list.change(load_block, [blocks_state, block_list], [var, value, prompt, system, output])
|
| 168 |
+
|
| 169 |
+
# Update block fields
|
| 170 |
+
def save_block(blocks, idx, v, val, p, s):
|
| 171 |
+
if idx is None:
|
| 172 |
+
return blocks
|
| 173 |
+
i = int(idx.split(":")[0])
|
| 174 |
+
blocks[i].update({
|
| 175 |
+
"var": v,
|
| 176 |
+
"value": val,
|
| 177 |
+
"prompt": p,
|
| 178 |
+
"system": s
|
| 179 |
+
})
|
| 180 |
+
return blocks
|
| 181 |
+
|
| 182 |
+
var.change(save_block, [blocks_state, block_list, var, value, prompt, system], blocks_state)
|
| 183 |
+
value.change(save_block, [blocks_state, block_list, var, value, prompt, system], blocks_state)
|
| 184 |
+
prompt.change(save_block, [blocks_state, block_list, var, value, prompt, system], blocks_state)
|
| 185 |
+
system.change(save_block, [blocks_state, block_list, var, value, prompt, system], blocks_state)
|
| 186 |
+
|
| 187 |
+
# Run flow
|
| 188 |
+
run_btn.click(run_flow, blocks_state, [blocks_state, variables_out, logs])
|
| 189 |
|
| 190 |
demo.launch()
|