TheEdict's picture
Use mo.ui.chat like official marimo chatbot example
702f0c7 verified
Raw
History Blame Contribute Delete
4.96 kB
# /// script
# requires-python = ">=3.10"
# dependencies = [
# "marimo",
# "gqlalchemy",
# "requests",
# "plotly",
# "pydantic-ai",
# ]
# ///
import marimo
__generated_with = "0.9.0"
app = marimo.App()
@app.cell
def _():
"""Import everything once"""
import marimo as mo
import requests
import json
import os
from gqlalchemy import Memgraph
import plotly.graph_objects as go
return mo, requests, json, os, Memgraph, go
@app.cell
def _(mo):
"""Header"""
mo.md("# πŸ¦€ VerdantClaw-Secure")
mo.md("**Flow Engineering Requirements System**")
mo.md("---")
return
@app.cell
def _(mo, requests):
"""Chat with ZeroClaw using mo.ui.chat"""
mo.md("""
## πŸ’¬ Chat with ZeroClaw
**ZeroClaw** - AI Gateway (uses OmniRoute)
ZeroClaw manages OAuth accounts for Claude Code, Codex, etc.
""")
def on_message(message: str, history: list):
"""Handle chat messages"""
try:
response = requests.post(
"http://localhost:42617/webhook",
json={"message": message},
timeout=120
)
if response.status_code == 200:
result = response.json()
return {"content": result.get('response', 'No response')}
else:
return {"content": f"❌ Error {response.status_code}"}
except Exception as e:
return {"content": f"❌ Connection error: {e}"}
def on_tool(name: str, args: dict):
"""Handle tool calls (for future extensions)"""
return {"result": "Tool not implemented"}
chatbot = mo.ui.chat(
on_message=on_message,
on_tool=on_tool,
tools=[], # Add tools here later if needed
prompts=[
"List all files in /app/workspace",
"Create a requirement file",
"Show me the requirements"
]
)
chatbot # Display the chatbot
return chatbot
@app.cell
def _(mo, os):
"""Requirements Browser"""
mo.md("### πŸ“‹ Requirements Browser")
workspace_path = "/app/workspace/Requirements"
if os.path.exists(workspace_path):
files = [f for f in os.listdir(workspace_path) if f.endswith('.md')]
if files:
file_list = "\n".join([f"- πŸ“„ `{f}`" for f in sorted(files)])
mo.md(f"**Found {len(files)} requirements:**\n\n{file_list}")
else:
mo.md("πŸ“­ No requirements yet")
else:
mo.md("⚠️ Requirements directory doesn't exist")
return
@app.cell
def _(mo, os):
"""Requirements Editor"""
mo.md("### ✏️ Requirements Editor")
filename = mo.ui.text(label="Filename:", value="REQ-001.md")
content = mo.ui.text_area(
label="Content:",
value="# REQ-001: Requirement Title\n\n## Description\nDescribe here...\n",
full_width=True,
height=300
)
def save_req(name, text):
workspace_path = "/app/workspace/Requirements"
os.makedirs(workspace_path, exist_ok=True)
filepath = os.path.join(workspace_path, name)
try:
with open(filepath, 'w') as f:
f.write(text)
return mo.md(f"βœ… Saved: `{filepath}`")
except Exception as e:
return mo.md(f"❌ Error: {e}")
save_btn = mo.ui.run_button(label="πŸ’Ύ Save")
if save_btn.value:
save_req(filename.value, content.value)
mo.vstack([filename, content, save_btn])
return
@app.cell
def _(mo, go):
"""Graph Visualization"""
mo.md("### πŸ“Š Graph")
fig = go.Figure(data=[go.Scatter(
x=[1, 2, 3, 4, 5], y=[1, 2, 3, 4, 5],
mode='markers+text',
text=['REQ-001', 'REQ-002', 'REQ-003'],
marker=dict(size=20, color='lightblue')
)])
fig.update_layout(title="Sample Graph", showlegend=False)
mo.ui.plotly(fig)
return
@app.cell
def _(mo, os):
"""Memory Editor"""
mo.md("### 🧠 Memory")
memory_path = "/app/workspace/MEMORY.md"
def load_mem():
if os.path.exists(memory_path):
with open(memory_path, 'r') as f:
return f.read()
return "# Memory\n\nStart writing..."
memory = mo.ui.text_area(
label="Memory:",
value=load_mem(),
full_width=True,
height=300
)
save_btn = mo.ui.run_button(label="πŸ’Ύ Save")
if save_btn.value:
os.makedirs(os.path.dirname(memory_path), exist_ok=True)
with open(memory_path, 'w') as f:
f.write(memory.value)
mo.md("βœ… Saved!")
mo.vstack([memory, save_btn])
return
@app.cell
def _(mo):
"""Footer"""
mo.md("---")
mo.md("**VerdantClaw-Secure** | Powered by Marimo Β· ZeroClaw Β· Memgraph Β· OmniRoute")
return
if __name__ == "__main__":
app.run()