Created
April 16, 2026 08:33
-
-
Save iggyughgi-glitch/b04bdce2a9354a01f24d8a7f9a50ecdf to your computer and use it in GitHub Desktop.
N
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html> | |
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Agent-Flow Mobile Fix</title> | |
| <script src="https://unpkg.com/react@18/umd/react.production.min.js"></script> | |
| <script src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script> | |
| <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script> | |
| <style> | |
| @import url('https://fonts.googleapis.com/css2?family=Space+Mono&family=Syne:wght@800&display=swap'); | |
| body { margin: 0; background: #0d0f14; color: #e2e8f0; font-family: 'Space Mono', monospace; font-size: 14px; } | |
| .node { animation: fadeIn 0.4s ease-out; background: #181c27; border: 1px solid #252a3a; borderRadius: 12px; padding: 15px; margin-bottom: 15px; } | |
| @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } } | |
| input, textarea, button { font-family: 'Space Mono', monospace; width: 100%; box-sizing: border-box; } | |
| </style> | |
| </head> | |
| <body> | |
| <div id="root"></div> | |
| <script type="text/babel"> | |
| const { useState } = React; | |
| function App() { | |
| const [task, setTask] = useState(""); | |
| const [apiKey, setApiKey] = useState(localStorage.getItem("ant_key") || ""); | |
| const [nodes, setNodes] = useState([]); | |
| const [loading, setLoading] = useState(false); | |
| const callClaude = async (messages, system) => { | |
| // We wrap the URL in a CORS proxy to bypass browser security | |
| const targetUrl = "https://api.anthropic.com/v1/messages"; | |
| const proxiedUrl = `https://corsproxy.io/?${encodeURIComponent(targetUrl)}`; | |
| const response = await fetch(proxiedUrl, { | |
| method: "POST", | |
| headers: { | |
| "Content-Type": "application/json", | |
| "x-api-key": apiKey, | |
| "anthropic-version": "2023-06-01" | |
| }, | |
| body: JSON.stringify({ | |
| model: "claude-3-haiku-20240307", // Using Haiku for speed on mobile | |
| max_tokens: 1024, | |
| system, | |
| messages, | |
| }), | |
| }); | |
| if (!response.ok) { | |
| const errorData = await response.json(); | |
| throw new Error(errorData.error?.message || "API Error"); | |
| } | |
| const data = await response.json(); | |
| return data.content[0].text; | |
| }; | |
| const runAgent = async () => { | |
| if (!apiKey || !task) return alert("Enter Key and Task"); | |
| setLoading(true); | |
| setNodes([{ id: '1', type: 'TRIGGER', title: task, status: 'done' }]); | |
| try { | |
| // Planning | |
| const planNode = { id: '2', type: 'PLAN', title: "Architecting Workflow", status: 'running' }; | |
| setNodes(prev => [...prev, planNode]); | |
| const system = "You are an AI agent. Respond ONLY in JSON: { \"plan\": [ { \"id\": \"s1\", \"title\": \"Step Name\", \"desc\": \"...\" } ] }"; | |
| const planText = await callClaude([{ role: "user", content: `Task: ${task}` }], system); | |
| const plan = JSON.parse(planText.replace(/```json|```/g, "")).plan; | |
| setNodes(prev => prev.map(n => n.id === '2' ? {...n, status: 'done', output: plan.map(s => s.title).join('\n')} : n)); | |
| // Execution | |
| for (const step of plan) { | |
| const stepNode = { id: step.id, type: 'EXECUTE', title: step.title, status: 'running' }; | |
| setNodes(prev => [...prev, stepNode]); | |
| const res = await callClaude([{ role: "user", content: `Do: ${step.title}. ${step.desc}` }], "Be thorough."); | |
| setNodes(prev => prev.map(n => n.id === step.id ? {...n, status: 'done', output: res} : n)); | |
| } | |
| } catch (e) { | |
| setNodes(prev => [...prev, { id: 'err', type: 'ERROR', title: "Failed", output: e.message }]); | |
| } finally { | |
| setLoading(false); | |
| } | |
| }; | |
| return ( | |
| <div style={{ padding: '20px' }}> | |
| <h2 style={{ color: '#3d7fff', fontFamily: 'Syne' }}>AGENT·FLOW</h2> | |
| <input type="password" value={apiKey} placeholder="Paste API Key" | |
| onChange={e => {setApiKey(e.target.value); localStorage.setItem("ant_key", e.target.value)}} | |
| style={{ background: '#13161e', border: '1px solid #252a3a', color: '#fff', padding: '12px', borderRadius: '8px', marginBottom: '10px' }} /> | |
| <textarea value={task} placeholder="What is the task?" | |
| onChange={e => setTask(e.target.value)} | |
| style={{ background: '#13161e', border: '1px solid #252a3a', color: '#fff', padding: '12px', borderRadius: '8px', marginBottom: '10px', height: '80px' }} /> | |
| <button onClick={runAgent} disabled={loading} | |
| style={{ background: '#3d7fff', color: '#fff', border: 'none', padding: '15px', borderRadius: '8px', fontWeight: 'bold' }}> | |
| {loading ? "WORKING..." : "LAUNCH AGENT"} | |
| </button> | |
| <div style={{ marginTop: '30px' }}> | |
| {nodes.map(n => ( | |
| <div key={n.id} className="node"> | |
| <div style={{ fontSize: '10px', color: '#3d7fff', fontWeight: 'bold' }}>{n.type}</div> | |
| <div style={{ fontWeight: 'bold', margin: '5px 0' }}>{n.title}</div> | |
| {n.output && <div style={{ fontSize: '12px', color: '#64748b', borderTop: '1px solid #252a3a', paddingTop: '8px', marginTop: '8px' }}>{n.output}</div>} | |
| </div> | |
| ))} | |
| </div> | |
| </div> | |
| ); | |
| } | |
| const root = ReactDOM.createRoot(document.getElementById('root')); | |
| root.render(<App />); | |
| </script> | |
| </body> | |
| </html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment