mirror of
https://github.com/multipleof4/sune.git
synced 2026-05-18 03:02:15 +00:00
Compare commits
6 Commits
53ba91caaf
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4fcda90f81 | ||
| 0a3d8093cb | |||
|
|
7b650e0c3b | ||
| cbfb79257b | |||
|
|
6db81f99fe | ||
| 67dc535244 |
@@ -807,7 +807,7 @@ var __vitePreload = function preload(baseModule, deps, importerUrl) {
|
|||||||
o != k && ((k = o) ? (history.pushState({ k: 1 }, ""), addEventListener("popstate", f)) : (removeEventListener("popstate", f), history.state?.k && history.back()));
|
o != k && ((k = o) ? (history.pushState({ k: 1 }, ""), addEventListener("popstate", f)) : (removeEventListener("popstate", f), history.state?.k && history.back()));
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
var DEFAULT_MODEL = "anthropic/claude-opus-4.6";
|
var DEFAULT_MODEL = "anthropic/claude-opus-4.7";
|
||||||
var icons = () => window.lucide && lucide.createIcons();
|
var icons = () => window.lucide && lucide.createIcons();
|
||||||
var haptic = () => /android/i.test(navigator.userAgent) && navigator.vibrate?.(1);
|
var haptic = () => /android/i.test(navigator.userAgent) && navigator.vibrate?.(1);
|
||||||
var su = {
|
var su = {
|
||||||
@@ -2199,7 +2199,14 @@ async function syncActiveThread() {
|
|||||||
setBtnStop();
|
setBtnStop();
|
||||||
}
|
}
|
||||||
const bubble = getBubbleById(id);
|
const bubble = getBubbleById(id);
|
||||||
if (!bubble) return false;
|
if (!bubble) {
|
||||||
|
if (state.busy) {
|
||||||
|
setBtnSend();
|
||||||
|
state.busy = false;
|
||||||
|
state.controller = null;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
const msgIdx = state.messages.findIndex((x) => x.id === id);
|
const msgIdx = state.messages.findIndex((x) => x.id === id);
|
||||||
const localText = msgIdx >= 0 ? partsToText(state.messages[msgIdx]) : bubble.textContent || "";
|
const localText = msgIdx >= 0 ? partsToText(state.messages[msgIdx]) : bubble.textContent || "";
|
||||||
const j = await fetch(HTTP_BASE + "?uid=" + encodeURIComponent(id)).then((r) => r.ok ? r.json() : null).catch(() => null);
|
const j = await fetch(HTTP_BASE + "?uid=" + encodeURIComponent(id)).then((r) => r.ok ? r.json() : null).catch(() => null);
|
||||||
@@ -2233,6 +2240,13 @@ async function syncActiveThread() {
|
|||||||
type: "text",
|
type: "text",
|
||||||
text: t
|
text: t
|
||||||
}]);
|
}]);
|
||||||
|
} else {
|
||||||
|
await cacheStore.setItem(id, "done");
|
||||||
|
if (state.busy) {
|
||||||
|
setBtnSend();
|
||||||
|
state.busy = false;
|
||||||
|
state.controller = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -2,8 +2,7 @@
|
|||||||
:root{--safe-bottom:env(safe-area-inset-bottom)}
|
:root{--safe-bottom:env(safe-area-inset-bottom)}
|
||||||
::-webkit-scrollbar{height:8px;width:8px}
|
::-webkit-scrollbar{height:8px;width:8px}
|
||||||
::-webkit-scrollbar-thumb{background:#e5e7eb;border-radius:999px}
|
::-webkit-scrollbar-thumb{background:#e5e7eb;border-radius:999px}
|
||||||
.no-scrollbar::-webkit-scrollbar{display:none}
|
@media(pointer: coarse){.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}}
|
||||||
.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}
|
|
||||||
html,body{overscroll-behavior-y:contain;font-family:'Assistant',sans-serif}
|
html,body{overscroll-behavior-y:contain;font-family:'Assistant',sans-serif}
|
||||||
.markdown-body{font-size:14px;line-height:1.6}
|
.markdown-body{font-size:14px;line-height:1.6}
|
||||||
.markdown-body pre{overflow:auto}
|
.markdown-body pre{overflow:auto}
|
||||||
4
dist/index.html
vendored
4
dist/index.html
vendored
@@ -13,8 +13,8 @@
|
|||||||
<script defer src="//unpkg.com/alpinejs"></script>
|
<script defer src="//unpkg.com/alpinejs"></script>
|
||||||
|
|
||||||
|
|
||||||
<script type="module" crossorigin src="/assets/index-B0f8K1Up.js"></script>
|
<script type="module" crossorigin src="/assets/index-DVG7SzRn.js"></script>
|
||||||
<link rel="stylesheet" crossorigin href="/assets/index-CLEI5Rwr.css">
|
<link rel="stylesheet" crossorigin href="/assets/index-DaGRC7Kr.css">
|
||||||
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
<link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
|
||||||
<body class="bg-white text-gray-900 selection:bg-black/10" x-data @click.window="if($event.target.closest('button')) haptic(); if(!document.getElementById('threadPopover').contains($event.target)&&!$event.target.closest('[data-thread-menu]')) hideThreadPopover(); if(!document.getElementById('sunePopover').contains($event.target)&&!$event.target.closest('[data-sune-menu]')) hideSunePopover(); if(!document.getElementById('userMenu').contains($event.target)&&!document.getElementById('userMenuBtn').contains($event.target)) document.getElementById('userMenu').classList.add('hidden')">
|
<body class="bg-white text-gray-900 selection:bg-black/10" x-data @click.window="if($event.target.closest('button')) haptic(); if(!document.getElementById('threadPopover').contains($event.target)&&!$event.target.closest('[data-thread-menu]')) hideThreadPopover(); if(!document.getElementById('sunePopover').contains($event.target)&&!$event.target.closest('[data-sune-menu]')) hideSunePopover(); if(!document.getElementById('userMenu').contains($event.target)&&!document.getElementById('userMenuBtn').contains($event.target)) document.getElementById('userMenu').classList.add('hidden')">
|
||||||
<div class="flex flex-col h-dvh max-h-dvh overflow-hidden">
|
<div class="flex flex-col h-dvh max-h-dvh overflow-hidden">
|
||||||
|
|||||||
2
dist/sw.js
vendored
2
dist/sw.js
vendored
@@ -1 +1 @@
|
|||||||
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let o={};const l=e=>i(e,t),c={module:{uri:t},exports:o,require:l};s[t]=Promise.all(n.map(e=>c[e]||l(e))).then(e=>(r(...e),o))}}define(["./workbox-8c29f6e4"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"index.html",revision:"fb75df16810eff6c92da1018af150a35"},{url:"assets/index-CLEI5Rwr.css",revision:null},{url:"assets/index-B0f8K1Up.js",revision:null},{url:"manifest.webmanifest",revision:"7a6c5c6ab9cb5d3605d21df44c6b17a2"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});
|
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let o={};const d=e=>i(e,t),l={module:{uri:t},exports:o,require:d};s[t]=Promise.all(n.map(e=>l[e]||d(e))).then(e=>(r(...e),o))}}define(["./workbox-9c191d2f"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"index.html",revision:"af2178b9db3800fa6deda68db3fe0707"},{url:"assets/index-DaGRC7Kr.css",revision:null},{url:"assets/index-DVG7SzRn.js",revision:null},{url:"manifest.webmanifest",revision:"7a6c5c6ab9cb5d3605d21df44c6b17a2"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))});
|
||||||
|
|||||||
1
dist/workbox-8c29f6e4.js
vendored
1
dist/workbox-8c29f6e4.js
vendored
File diff suppressed because one or more lines are too long
1
dist/workbox-9c191d2f.js
vendored
Normal file
1
dist/workbox-9c191d2f.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -13,7 +13,7 @@ import { titleFrom, serializeThreadName, deserializeThreadName } from './threads
|
|||||||
import { resolveSuneSrc, processSuneIncludes, renderSuneHTML } from './sune-html.js';
|
import { resolveSuneSrc, processSuneIncludes, renderSuneHTML } from './sune-html.js';
|
||||||
|
|
||||||
(()=>{let k,v=visualViewport;const f=()=>{removeEventListener('popstate',f),document.activeElement?.blur()};v.onresize=()=>{let o=v.height<innerHeight;o!=k&&((k=o)?(history.pushState({k:1},''),addEventListener('popstate',f)):(removeEventListener('popstate',f),history.state?.k&&history.back()))}})()
|
(()=>{let k,v=visualViewport;const f=()=>{removeEventListener('popstate',f),document.activeElement?.blur()};v.onresize=()=>{let o=v.height<innerHeight;o!=k&&((k=o)?(history.pushState({k:1},''),addEventListener('popstate',f)):(removeEventListener('popstate',f),history.state?.k&&history.back()))}})()
|
||||||
const DEFAULT_MODEL='anthropic/claude-opus-4.6'
|
const DEFAULT_MODEL='anthropic/claude-opus-4.7'
|
||||||
const icons=()=>window.lucide&&lucide.createIcons()
|
const icons=()=>window.lucide&&lucide.createIcons()
|
||||||
const haptic=()=>/android/i.test(navigator.userAgent)&&navigator.vibrate?.(1)
|
const haptic=()=>/android/i.test(navigator.userAgent)&&navigator.vibrate?.(1)
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ el.exportAccountSettings.onclick=()=>dl(`sune-account-${ts()}.json`,{v:1,provide
|
|||||||
el.importAccountSettings.onclick=()=>{el.importAccountSettingsInput.value='';el.importAccountSettingsInput.click()};
|
el.importAccountSettings.onclick=()=>{el.importAccountSettingsInput.value='';el.importAccountSettingsInput.click()};
|
||||||
el.importAccountSettingsInput.onchange=async e=>{const f=e.target.files?.[0];if(!f)return;try{const d=JSON.parse(await f.text());if(!d||typeof d!=='object')throw new Error('Invalid');const m={provider:'provider',apiKeyOpenRouter:'apiKeyOR',apiKeyOpenAI:'apiKeyOAI',apiKeyGoogle:'apiKeyG',apiKeyClaude:'apiKeyC',apiKeyCloudflare:'apiKeyCF',customKey1:'customKey1',masterPrompt:'masterPrompt',titleModel:'titleModel',githubToken:'ghToken',name:'userName',avatar:'userAvatar'};Object.entries(m).forEach(([p,k])=>{const v=d[p]??d[k];if(typeof v==='string')USER[p]=v});openAccountSettings();alert('Imported.')}catch{alert('Import failed')}};
|
el.importAccountSettingsInput.onchange=async e=>{const f=e.target.files?.[0];if(!f)return;try{const d=JSON.parse(await f.text());if(!d||typeof d!=='object')throw new Error('Invalid');const m={provider:'provider',apiKeyOpenRouter:'apiKeyOR',apiKeyOpenAI:'apiKeyOAI',apiKeyGoogle:'apiKeyG',apiKeyClaude:'apiKeyC',apiKeyCloudflare:'apiKeyCF',customKey1:'customKey1',masterPrompt:'masterPrompt',titleModel:'titleModel',githubToken:'ghToken',name:'userName',avatar:'userAvatar'};Object.entries(m).forEach(([p,k])=>{const v=d[p]??d[k];if(typeof v==='string')USER[p]=v});openAccountSettings();alert('Imported.')}catch{alert('Import failed')}};
|
||||||
const getBubbleById=id=>el.messages.querySelector(`.msg-bubble[data-mid="${CSS.escape(id)}"]`)
|
const getBubbleById=id=>el.messages.querySelector(`.msg-bubble[data-mid="${CSS.escape(id)}"]`)
|
||||||
async function syncActiveThread(){const id=THREAD.getLastAssistantMessageId();if(!id)return false;if(await cacheStore.getItem(id)==='done'){if(state.busy){setBtnSend();state.busy=false;state.controller=null}return false}if(!state.busy){state.busy=true;state.controller={abort:()=>{const ws=new WebSocket(HTTP_BASE.replace('https','wss'));ws.onopen=function(){this.send(JSON.stringify({type:'stop',rid:id}));this.close()}}};setBtnStop()}const bubble=getBubbleById(id);if(!bubble)return false;const msgIdx=state.messages.findIndex(x=>x.id===id);const localText=msgIdx>=0?partsToText(state.messages[msgIdx]):(bubble.textContent||'');const j=await(fetch(HTTP_BASE+'?uid='+encodeURIComponent(id)).then(r=>r.ok?r.json():null).catch(()=>null));const finalise=(t,c,imgs)=>{const tempMsg={content:c,images:imgs};renderMarkdown(bubble,partsToText(tempMsg),{enhance:false});enhanceCodeBlocks(bubble,true);if(msgIdx>=0){state.messages[msgIdx].content=c;state.messages[msgIdx].images=imgs}else state.messages.push({id,role:'assistant',content:c,images:imgs,...activeMeta()});THREAD.persist();setBtnSend();state.busy=false;cacheStore.setItem(id,'done');state.controller=null;el.composer.dispatchEvent(new CustomEvent('sune:newSuneResponse',{detail:{message:state.messages.find(m=>m.id===id)}}))};if(!j||j.rid!==id){if(j&&j.error){const t=localText+'\n\n'+j.error;finalise(t,[{type:'text',text:t}])}return false}const serverText=j.text||'',isDone=j.error||j.done||j.phase==='done';const finalText=(serverText.length>=localText.length||isDone)?serverText:localText;const display=partsToText({content:[{type:'text',text:finalText}],images:j.images});if(display)renderMarkdown(bubble,display,{enhance:false});if(isDone){if(finalText!==localText){finalise(finalText,[{type:'text',text:finalText}],j.images)}else{await cacheStore.setItem(id,'done');if(state.busy){setBtnSend();state.busy=false;state.controller=null}}return false}await cacheStore.setItem(id,'busy');return true}
|
async function syncActiveThread(){const id=THREAD.getLastAssistantMessageId();if(!id)return false;if(await cacheStore.getItem(id)==='done'){if(state.busy){setBtnSend();state.busy=false;state.controller=null}return false}if(!state.busy){state.busy=true;state.controller={abort:()=>{const ws=new WebSocket(HTTP_BASE.replace('https','wss'));ws.onopen=function(){this.send(JSON.stringify({type:'stop',rid:id}));this.close()}}};setBtnStop()}const bubble=getBubbleById(id);if(!bubble){if(state.busy){setBtnSend();state.busy=false;state.controller=null;}return false;}const msgIdx=state.messages.findIndex(x=>x.id===id);const localText=msgIdx>=0?partsToText(state.messages[msgIdx]):(bubble.textContent||'');const j=await(fetch(HTTP_BASE+'?uid='+encodeURIComponent(id)).then(r=>r.ok?r.json():null).catch(()=>null));const finalise=(t,c,imgs)=>{const tempMsg={content:c,images:imgs};renderMarkdown(bubble,partsToText(tempMsg),{enhance:false});enhanceCodeBlocks(bubble,true);if(msgIdx>=0){state.messages[msgIdx].content=c;state.messages[msgIdx].images=imgs}else state.messages.push({id,role:'assistant',content:c,images:imgs,...activeMeta()});THREAD.persist();setBtnSend();state.busy=false;cacheStore.setItem(id,'done');state.controller=null;el.composer.dispatchEvent(new CustomEvent('sune:newSuneResponse',{detail:{message:state.messages.find(m=>m.id===id)}}))};if(!j||j.rid!==id){if(j&&j.error){const t=localText+'\n\n'+j.error;finalise(t,[{type:'text',text:t}])}else{await cacheStore.setItem(id,'done');if(state.busy){setBtnSend();state.busy=false;state.controller=null;}}return false}const serverText=j.text||'',isDone=j.error||j.done||j.phase==='done';const finalText=(serverText.length>=localText.length||isDone)?serverText:localText;const display=partsToText({content:[{type:'text',text:finalText}],images:j.images});if(display)renderMarkdown(bubble,display,{enhance:false});if(isDone){if(finalText!==localText){finalise(finalText,[{type:'text',text:finalText}],j.images)}else{await cacheStore.setItem(id,'done');if(state.busy){setBtnSend();state.busy=false;state.controller=null}}return false}await cacheStore.setItem(id,'busy');return true}
|
||||||
let syncLoopRunning=false
|
let syncLoopRunning=false
|
||||||
async function syncWhileBusy(){if(syncLoopRunning||document.visibilityState==='hidden')return;syncLoopRunning=true;try{while(await syncActiveThread())await new Promise(r=>setTimeout(r,1500))}finally{syncLoopRunning=false}}
|
async function syncWhileBusy(){if(syncLoopRunning||document.visibilityState==='hidden')return;syncLoopRunning=true;try{while(await syncActiveThread())await new Promise(r=>setTimeout(r,1500))}finally{syncLoopRunning=false}}
|
||||||
const onForeground=()=>{if(document.visibilityState!=='visible')return;state.controller?.disconnect?.();if(state.busy)syncWhileBusy()}
|
const onForeground=()=>{if(document.visibilityState!=='visible')return;state.controller?.disconnect?.();if(state.busy)syncWhileBusy()}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
@import url(https://fonts.bunny.net/css?family=assistant:500);
|
@import url(https://fonts.bunny.net/css?family=assistant:500);
|
||||||
:root{--safe-bottom:env(safe-area-inset-bottom)}::-webkit-scrollbar{height:8px;width:8px}::-webkit-scrollbar-thumb{background:#e5e7eb;border-radius:999px}.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}
|
:root{--safe-bottom:env(safe-area-inset-bottom)}::-webkit-scrollbar{height:8px;width:8px}::-webkit-scrollbar-thumb{background:#e5e7eb;border-radius:999px}@media(pointer: coarse){.no-scrollbar::-webkit-scrollbar{display:none}.no-scrollbar{-ms-overflow-style:none;scrollbar-width:none}}
|
||||||
html,body{overscroll-behavior-y:contain;font-family:'Assistant',sans-serif}
|
html,body{overscroll-behavior-y:contain;font-family:'Assistant',sans-serif}
|
||||||
.markdown-body{font-size:14px;line-height:1.6}.markdown-body pre{overflow:auto}
|
.markdown-body{font-size:14px;line-height:1.6}.markdown-body pre{overflow:auto}
|
||||||
.markdown-body ul,.markdown-body ol{list-style:revert;padding-left:2em}
|
.markdown-body ul,.markdown-body ol{list-style:revert;padding-left:2em}
|
||||||
|
|||||||
Reference in New Issue
Block a user