From 96649822122b70e7c7aa908b02aa77fbca5471e8 Mon Sep 17 00:00:00 2001 From: multipleof4 Date: Tue, 9 Sep 2025 07:56:57 -0700 Subject: [PATCH] Sync: Update sune 'Agent' --- agent.sune | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/agent.sune b/agent.sune index a7807b7..810e617 100644 --- a/agent.sune +++ b/agent.sune @@ -1 +1 @@ -[{"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":1757426102129,"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 (preferred) 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":"
\n 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>>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
\n
\n \n Agent Control\n
\n \n
\n\n
\n \n \n \n \n
\n\n
\n \n\n
\n
\n        
\n \n \n \n
\n
\n
\n
\n\n","extension_html":"","hide_composer":false},"storage":{}}] \ No newline at end of file +[{"id":"cjnh9pp","name":"Agent","pinned":false,"avatar":"data:image/webp;base64,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","url":"gh://sune-org/store/agent.sune","updatedAt":1757429818443,"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 (preferred) 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.\n\nAccessing individual API keys:\nwindow.USER.apiKeyOpenRouter\nwindow.USER.apiKeyOpenAI\nwindow.USER.apiKeyGoogle\nwindow.USER.apiKeyCloudflare\nwindow.USER.githubToken","html":"
\n localStorage.setItem(this.storageKey, v));\n $watch('logs', v=>localStorage.setItem(this.logStorageKey, JSON.stringify(v)));\n\n // Watch Sune switching\n this.startSuneWatcher();\n\n this.$nextTick(()=>this.scrollConsole());\n },\n\n bindComposer(){\n const $c=$('#composer');\n // Ensure previous handlers for this ns are cleared before rebinding\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 // Optional platform event for switching (if emitted)\n $c.off(`sune:changed${this.ns}`).on(`sune:changed${this.ns}`, e=>this.onSuneChanged(e?.detail?.id||window.SUNE?.id));\n },\n\n startSuneWatcher(){\n try{ clearInterval(this.idPoll) }catch{};\n this.idPoll=setInterval(()=>{ const id=window.SUNE?.id; if(id && id!==this.currentSuneId) this.onSuneChanged(id) },500);\n },\n\n onSuneChanged(newId){\n if(!newId || newId===this.currentSuneId) return;\n try{ $('#composer').off(`.sag-${this.currentSuneId}`) }catch{};\n const prev=this.currentSuneId; this.currentSuneId=newId; this.ns=`.sag-${newId}`;\n this.storageKey=`sune_agent_panel_active_${newId}`;\n this.logStorageKey=`sune_agent_panel_logs_${newId}`;\n this.processedKey=`sune_agent_processed_${newId}`;\n // Reload per-Sune state\n this.isActive = localStorage.getItem(this.storageKey)==='true';\n this.logs = JSON.parse(localStorage.getItem(this.logStorageKey)||'[]');\n try{ this.processed = new Set(JSON.parse(localStorage.getItem(this.processedKey)||'[]')) }catch{ this.processed = new Set() }\n // Cleanup canvas to avoid bleed\n this.clearCanvas();\n // Rebind for new Sune\n this.bindComposer();\n this.log('SYS',`Switched Sune ${prev||'-'} -> ${newId}`);\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>>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 // Ignore events not for current Sune if id present\n const curId=this.currentSuneId||window.SUNE?.id;\n const evtId=e?.detail?.suneId||e?.detail?.sune?.id||msg?.suneId||msg?.sune?.id;\n if(evtId && evtId!==curId){ this.log('SKIP',`Ignored event for ${evtId}`); 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
\n
\n \n Agent Control\n
\n \n
\n\n
\n \n \n \n \n
\n\n
\n \n\n
\n
\n        
\n \n \n \n
\n
\n
\n
\n\n","extension_html":"","hide_composer":false},"storage":{}}] \ No newline at end of file