Files
store/agent.sune

1 line
15 KiB
JSON

[{"id":"cjnh9pp","name":"Agent Control Panel","pinned":false,"avatar":"data:image/webp;base64,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","url":"gh://sune-org/store/agent.sune","updatedAt":1757425825256,"settings":{"model":"g:gemini-2.5-flash","temperature":"","top_p":"","top_k":"","frequency_penalty":"","repetition_penalty":"","min_p":"","top_a":"","verbosity":"","reasoning_effort":"default","system_prompt":"You are an agent. Depending on the task, you may return partial html or JavaScript. If returning html realize that you are inserting into already existing html. Tailwind, lucide, dom-cash, alpinejs are available. When you return code, it runs immediately.","html":"<div class=\"p-3 sm:p-4\">\n <div\n x-data=\"{\n // UI\n isActive:false,\n isConsoleOpen:false,\n version:'v0.5.0',\n\n // Logs\n logs:[],\n storageKey:`sune_agent_panel_active_${window.SUNE.id}`,\n logStorageKey:`sune_agent_panel_logs_${window.SUNE.id}`,\n\n // De-dupe\n ns:'',\n processed:new Set(),\n processedKey:`sune_agent_processed_${window.SUNE.id}`,\n\n // Mount info\n mountId:'agent-runtime',\n\n init(){\n // Restore UI + logs\n this.isActive = localStorage.getItem(this.storageKey)==='true';\n this.logs = JSON.parse(localStorage.getItem(this.logStorageKey)||'[]');\n\n // Restore processed keys\n try{ this.processed = new Set(JSON.parse(localStorage.getItem(this.processedKey)||'[]')) }catch{ this.processed = new Set() }\n\n // Namespace per sune and bind once\n this.ns = `.sag-${window.SUNE.id}`;\n const $c = $('#composer');\n $c.off(`sune:newSuneResponse${this.ns}`).on(`sune:newSuneResponse${this.ns}`, e=>this.handleResponse(e));\n $c.off(`submit${this.ns}`).on(`submit${this.ns}`, ()=>this.injectContext());\n\n // Persist\n $watch('isActive', v=>localStorage.setItem(this.storageKey, v));\n $watch('logs', v=>localStorage.setItem(this.logStorageKey, JSON.stringify(v)));\n\n this.$nextTick(()=>this.scrollConsole());\n },\n\n // ------------- Utils -------------\n saveProcessed(){ try{ localStorage.setItem(this.processedKey, JSON.stringify([...this.processed].slice(-200))) }catch{} },\n markProcessed(k){ this.processed.add(k); this.saveProcessed() },\n hasProcessed(k){ return this.processed.has(k) },\n hash(s){ let h=0; for(let i=0;i<s.length;i++) h=((h<<5)-h)+s.charCodeAt(i)|0; return 'h'+(h>>>0).toString(16) },\n uid(){ return Date.now().toString(36)+Math.random().toString(36).slice(2,6) },\n\n log(type,msg){\n const ts=new Date().toLocaleTimeString();\n this.logs.push(`[${ts} ${type}] ${msg}`);\n if(this.logs.length>50) this.logs.shift();\n this.$nextTick(()=>this.scrollConsole());\n },\n scrollConsole(){ const el=this.$refs.console; if(el) el.scrollTop=el.scrollHeight },\n\n ensureMount(){\n const host=document.getElementById('suneHtml');\n if(!host){ this.log('WARN','#suneHtml not found'); return null }\n host.classList.remove('hidden');\n let mount=host.querySelector('#'+this.mountId);\n if(!mount){\n mount=document.createElement('div');\n mount.id=this.mountId;\n mount.className='agent-runtime space-y-2 p-2';\n host.appendChild(mount);\n }\n return mount;\n },\n\n injectHTMLBlock(html){\n const mount=this.ensureMount();\n if(!mount) return;\n const wrapId='agent-block-'+this.uid();\n // Build fragment\n const tpl=document.createElement('template');\n tpl.innerHTML=html;\n const frag=tpl.content.cloneNode(true);\n // Wrap to scope script execution and later cleanup\n const wrap=document.createElement('div');\n wrap.setAttribute('data-agent-block', wrapId);\n wrap.className='rounded-lg border border-gray-200 bg-white/50 p-2';\n wrap.appendChild(frag);\n mount.appendChild(wrap);\n\n // Recreate scripts after DOM insertion to ensure execution\n const runScripts=container=>{\n const scripts=[...container.querySelectorAll('script')];\n scripts.forEach(old=>{\n const s=document.createElement('script');\n // copy attributes (type, src, async, defer, etc.)\n [...old.attributes].forEach(a=>s.setAttribute(a.name,a.value));\n // inline code\n s.textContent=old.textContent||'';\n // replace to trigger execution\n old.parentNode?.replaceChild(s, old);\n });\n };\n runScripts(wrap);\n\n // Re-init Alpine within the newly added chunk\n try{ window.Alpine?.initTree?.(wrap) }catch(e){ this.log('WARN','Alpine init failed: '+(e?.message||'unknown')) }\n\n // Refresh Lucide icons if available\n try{ window.lucide?.createIcons?.() }catch{}\n\n this.log('HTML','Appended HTML to #suneHtml');\n },\n\n executeJSBlock(code){\n this.log('EXEC','Running JS block...');\n try{\n (new Function(code)).call(window);\n this.log('DONE','JS executed.');\n }catch(err){\n console.error('[Sune Agent] JS Execution Error:',err);\n this.log('ERROR', err?.message||'Execution failed');\n window.SUNE?.log?.(`Agent Error: ${err?.message||'Execution failed'}`);\n }\n },\n\n // ------------- Agent flow -------------\n handleResponse(e){\n if(!this.isActive) return;\n const msg=e?.detail?.message;\n if(!msg || msg.role!=='assistant' || !Array.isArray(msg.content)) return;\n\n const txt=msg.content.map(p=>p?.type==='text'?p.text:'').join('\\n');\n const msgKey=msg.id || this.hash(txt);\n\n // Avoid reprocessing same assistant message\n if(this.hasProcessed(msgKey)){ this.log('SKIP',`Already processed ${msgKey}`); return }\n\n // JS fences\n const reJS=/```(?:javascript|js)\\n([\\s\\S]*?)\\n```/gi;\n // HTML fences\n const reHTML=/```(?:html|htm)\\n([\\s\\S]*?)\\n```/gi;\n\n let any=false;\n\n // Execute JS blocks\n let mJS; \n while((mJS=reJS.exec(txt))!==null){\n const code=(mJS[1]||'').trim(); \n if(!code) continue;\n any=true;\n this.executeJSBlock(code);\n }\n\n // Inject HTML blocks\n let mHTML;\n while((mHTML=reHTML.exec(txt))!==null){\n const html=(mHTML[1]||'').trim();\n if(!html) continue;\n any=true;\n this.injectHTMLBlock(html);\n }\n\n if(any){\n this.markProcessed(msgKey);\n }\n },\n\n // ------------- Actions -------------\n injectContext(){\n if(!this.isActive || !this.logs.length) return;\n const input=$('#input'); const cur=String(input.val()||'');\n if(!cur.trim()) return;\n input.val(`[AGENT LOGS]\\n${this.logs.join('\\n')}\\n[/AGENT LOGS]\\n\\n`+cur);\n this.log('INFO','Injected logs into context for next message.');\n },\n\n clearLogs(){ this.logs=[]; this.log('INFO','Console cleared.') },\n\n clearExecHistory(){ this.processed.clear(); this.saveProcessed(); this.log('INFO','Execution history cleared.') },\n\n clearCanvas(){\n const mount=document.querySelector('#'+this.mountId);\n if(mount){ mount.innerHTML=''; this.log('INFO','Cleared injected HTML canvas.') }\n }\n }\"\n x-init=\"init()\"\n class=\"mx-auto w-full max-w-3xl rounded-xl border border-gray-200 bg-white p-3 shadow-sm\"\n >\n <div class=\"flex items-center justify-between gap-3\">\n <div class=\"flex items-center gap-2\">\n <i data-lucide=\"brain-circuit\" class=\"h-5 w-5 text-gray-600\"></i>\n <span class=\"text-sm font-medium text-gray-800\">Agent Control</span>\n </div>\n <span class=\"text-xs text-gray-400\" x-text=\"version\"></span>\n </div>\n\n <div class=\"mt-3 flex items-center justify-between rounded-lg bg-gray-100 p-2\">\n <label class=\"cursor-pointer text-sm text-gray-700\" x-text=\"isActive ? 'Status: Active' : 'Status: Inactive'\"></label>\n <button\n type=\"button\"\n role=\"switch\"\n :aria-checked=\"isActive\"\n @click=\"isActive=!isActive; log('SYS', isActive ? 'Agent Activated' : 'Agent Deactivated')\"\n :class=\"isActive ? 'bg-black' : 'bg-gray-300'\"\n class=\"relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none\"\n >\n <span :class=\"isActive ? 'translate-x-5' : 'translate-x-0'\" class=\"pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out\"></span>\n </button>\n </div>\n\n <div class=\"mt-2 border-t border-gray-200 pt-2\">\n <button @click=\"isConsoleOpen=!isConsoleOpen\" class=\"flex w-full items-center justify-between text-left text-sm font-medium text-gray-600 hover:text-black\">\n <span>Console</span>\n <i data-lucide=\"chevron-down\" class=\"h-4 w-4 transition-transform\" :class=\"isConsoleOpen && 'rotate-180'\"></i>\n </button>\n\n <div x-show=\"isConsoleOpen\" x-transition class=\"mt-2\">\n <pre x-ref=\"console\" class=\"max-h-48 overflow-y-auto rounded-md bg-gray-900 p-2 text-xs font-mono leading-relaxed text-white\" x-text=\"logs.join('\\n') || 'Console is empty.'\"></pre>\n <div class=\"mt-2 grid grid-cols-3 gap-2\">\n <button @click=\"clearLogs()\" class=\"flex items-center justify-center gap-2 rounded-md bg-gray-100 px-3 py-1.5 text-xs text-gray-600 hover:bg-gray-200\">\n <i data-lucide=\"trash-2\" class=\"h-3 w-3\"></i> Clear Logs\n </button>\n <button @click=\"clearExecHistory()\" class=\"flex items-center justify-center gap-2 rounded-md bg-gray-100 px-3 py-1.5 text-xs text-gray-600 hover:bg-gray-200\">\n <i data-lucide=\"rotate-ccw\" class=\"h-3 w-3\"></i> Forget Executions\n </button>\n <button @click=\"clearCanvas()\" class=\"flex items-center justify-center gap-2 rounded-md bg-gray-100 px-3 py-1.5 text-xs text-gray-600 hover:bg-gray-200\">\n <i data-lucide=\"eraser\" class=\"h-3 w-3\"></i> Clear Canvas\n </button>\n </div>\n </div>\n </div>\n </div>\n</div>\n","extension_html":"<sune src='https://raw.githubusercontent.com/sune-org/store/refs/heads/main/sync.sune' private />","hide_composer":false},"storage":{}}]