broadfield commited on
Commit
0312ebf
·
verified ·
1 Parent(s): 1ed42b2

V2 full code restore - hardcoded HF module path

Browse files
Files changed (1) hide show
  1. index.html +12 -314
index.html CHANGED
@@ -282,333 +282,31 @@ if(storageMode==="indexedDB"){
282
  renderChatHistory();
283
  var el=document.getElementById("storageModeSelect");
284
  if(el){el.value="localStorage";onStorageModeChange();}
285
- if(conversations.length>0)loadChat(conversations[0].id);else newChat();
286
  });
287
  } else {
288
  renderChatHistory();
289
  var el=document.getElementById("storageModeSelect");
290
- if(el){el.value=storageMode;onStorageModeChange();}
291
  setTimeout(function(){
292
- if(!currentChatId){
293
- if(conversations.length>0)loadChat(conversations[0].id);
294
- else newChat();
295
- }
296
- },50);
297
- }
298
 
299
  // ===== SANITIZATION UTILITIES =====
300
- function sanitizeHTML(str){if(typeof DOMPurify!=="undefined")return DOMPurify.sanitize(str,{ALLOWED_TAGS:[],ALLOWED_ATTR:[]});var d=document.createElement("div");d.textContent=str;return d.innerHTML;}
301
- function safeRenderHTML(html,allowSafeTags){try{if(typeof DOMPurify!=="undefined"){if(allowSafeTags)return DOMPurify.sanitize(html,{ALLOWED_TAGS:["div","span","a","b","i","em","strong","code","pre","br","p","h1","h2","h3","h4","h5","h6","ul","ol","li","blockquote","table","thead","tbody","tr","th","td","hr","img","figure","figcaption","dl","dt","dd","sup","sub","kbd","s","del","ins","mark","small","details","summary","button"],ALLOWED_ATTR:["href","target","rel","src","alt","class","id","title","width","height","style","data-*"],ALLOW_DATA_ATTR:true,FORBID_TAGS:["style","script","iframe","object","embed","form","input","textarea","select","option","optgroup","svg","math","link","meta","video","audio","canvas","applet","frame","frameset","noframes","noscript"],FORBID_ATTR:["onerror","onload","onclick","onmouseover","onmouseout","onkeydown","onkeyup","onchange","onsubmit","onfocus","onblur","onabort","onanimationstart","onanimationend","onauxclick","onbeforeinput","onbeforetoggle","oncancel","oncanplay","oncanplaythrough","onclose","oncontextmenu","oncopy","oncuechange","oncut","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onformdata","ongotpointercapture","oninput","oninvalid","onlostpointercapture","onpaste","onpause","onplay","onplaying","onpointercancel","onpointerenter","onpointerleave","onpointermove","onpointerout","onpointerover","onpointerrawupdate","onpointerup","onprogress","onratechange","onreset","onresize","onscroll","onsecuritypolicyviolation","onseeked","onseeking","onselect","onselectionchange","onselectstart","onslotchange","onstalled","onsubmit","onsuspend","ontimeupdate","ontoggle","ontransitioncancel","ontransitionend","ontransitionrun","ontransitionstart","onvolumechange","onwaiting","onwebkitanimationend","onwebkitanimationiteration","onwebkitanimationstart","onwebkittransitionend","onwheel","style"],ADD_ATTR:["target"],WHOLE_DOCUMENT:false});}return DOMPurify.sanitize(html);var d=document.createElement("div");d.textContent=html.replace(/<[^>]*>/g,"");return d.innerHTML;}catch(ex){var d=document.createElement("div");d.textContent=html;return d.innerHTML;}}
302
  function safeSetInnerHTML(el,html){try{el.innerHTML=html;}catch(ex){el.textContent=html;}}
303
- function renderMarkdown(text){if(!text)return "";try{var escaped=text.replace(/</g,"<").replace(/>/g,">");var raw=marked.parse(escaped,{breaks:true,gfm:true});return safeRenderHTML(raw,true);}catch(ex){var d=document.createElement("div");d.textContent=text;return d.innerHTML;}}
304
  function showToast(msg){var t=document.getElementById("toast");t.textContent=msg;t.classList.remove("hidden");clearTimeout(t._timeout);t._timeout=setTimeout(function(){t.classList.add("hidden");},3500);}
305
  function scrollToBottom(smooth){if(smooth===undefined)smooth=true;var c=document.getElementById("messages");c.scrollTop=c.scrollHeight;}
306
  function getTimeStr(){var d=new Date();return d.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});}
307
  function updateAutoScroll(){autoScroll=document.getElementById("autoScrollToggle").checked;}
308
- function getCurrentChat(){for(var i=0;i<conversations.length;i++)if(conversations[i].id===currentChatId)return conversations[i];return null;}
309
- function getStorageUsage(){var result={used:0,limit:5242880,pct:0};try{var total=0;for(var key in localStorage){if(localStorage.hasOwnProperty(key))total+=localStorage[key].length;}result.used=total;result.pct=Math.min(100,Math.round((total/result.limit)*100));}catch(ex){}return result;}
310
- function formatBytes(bytes){if(bytes<1024)return bytes+" B";if(bytes<1048576)return(bytes/1024).toFixed(1)+" KB";return(bytes/1048576).toFixed(1)+" MB";}
311
-
312
- function showConfirmDialog(msg,callback){confirmCallback=callback;var modal=document.getElementById("confirmModal");document.getElementById("confirmModalBody").textContent=msg;modal.classList.add("show");}
313
  document.getElementById("confirmOkBtn").addEventListener("click",function(){var cb=confirmCallback;confirmCallback=null;document.getElementById("confirmModal").classList.remove("show");if(cb)cb(true);});
314
  document.getElementById("confirmCancelBtn").addEventListener("click",function(){var cb=confirmCallback;confirmCallback=null;document.getElementById("confirmModal").classList.remove("show");if(cb)cb(false);});
315
 
316
- function saveConversations(){
317
- if(storageMode==="indexedDB"&&DB._ready){
318
- try{conversations.forEach(function(c){DB.saveConversation(c);});updateStorageIndicator();}catch(ex){}
319
- return;
320
- }
321
- try{var usage=getStorageUsage();var json=JSON.stringify(conversations);
322
- if(usage.pct>=STORAGE_CRIT_PCT){trimConversations(true);json=JSON.stringify(conversations);}
323
- else if(usage.pct>=STORAGE_WARN_PCT){trimConversations(false);json=JSON.stringify(conversations);}
324
- localStorage.setItem(STORAGE_KEY,json);updateStorageIndicator();
325
- }catch(ex){try{var cur=getCurrentChat();if(cur){var m=[{id:cur.id,title:cur.title,model:cur.model,messages:cur.messages.slice(-20),createdAt:cur.createdAt}];localStorage.setItem(STORAGE_KEY,JSON.stringify(m));conversations=m;showToast("Storage critical!");updateStorageIndicator();}}catch(ex2){showToast("Storage full!");}}
326
- }
327
-
328
- function trimConversations(force){
329
- if(!conversations||conversations.length===0)return;
330
- conversations.sort(function(a,b){var al=a.messages&&a.messages.length?new Date(a.messages[a.messages.length-1].timestamp||a.createdAt).getTime():new Date(a.createdAt).getTime();var bl=b.messages&&b.messages.length?new Date(b.messages[b.messages.length-1].timestamp||b.createdAt).getTime():new Date(b.createdAt).getTime();return bl-al;});
331
- for(var i=conversations.length-1;i>=1;i--){if(!conversations[i].messages||conversations[i].messages.length===0)conversations.splice(i,1);}
332
- while(conversations.length>MAX_CONVERSATIONS)conversations.pop();
333
- if(force){var now=Date.now();for(var i=conversations.length-1;i>=1;i--){var chat=conversations[i];if(!chat.messages)continue;if(now-new Date(chat.createdAt||now).getTime()>7*86400000&&chat.messages.length>10)chat.messages=chat.messages.slice(-10);}}
334
- }
335
-
336
- function updateStorageIndicator(){var el=document.getElementById("storageIndicator");if(!el)return;var u=getStorageUsage(),pct=u.pct;var c=pct>90?"text-red-400":pct>70?"text-yellow-400":"text-emerald-400";var bc=pct>90?"bg-red-500":pct>70?"bg-yellow-500":"bg-emerald-500";el.innerHTML='<div class="flex items-center gap-2 text-xs" title="Storage: '+formatBytes(u.used)+' / '+formatBytes(u.limit)+'"><div class="w-16 h-1.5 bg-gray-700 rounded-full overflow-hidden"><div class="h-full '+bc+' rounded-full" style="width:'+Math.min(pct,100)+'%"></div></div><span class="'+c+'">'+pct+'%</span></div>';}
337
- function addStorageIndicator(){var footer=document.querySelector(".left-sidebar-footer");if(!footer)return;var ind=document.createElement("div");ind.id="storageIndicator";ind.className="px-4 py-1";footer.parentNode.insertBefore(ind,footer);updateStorageIndicator();}
338
- function setProcessingUI(p){var s=document.getElementById("sendBtn"),c=document.getElementById("cancelBtn");if(!s||!c)return;if(p){s.classList.add("hidden");c.classList.remove("hidden");}else{s.classList.remove("hidden");c.classList.add("hidden");}}
339
- function updateTokenDisplay(){var chat=getCurrentChat();if(!chat)return;var t=0;for(var i=0;i<chat.messages.length;i++){if(chat.messages[i].content)t+=chat.messages[i].content.length;}var a=Math.round(t/4);document.getElementById("tokenUsage").textContent="~"+a+" tokens";document.getElementById("totalTokens").textContent=a;updateCostDisplay(a);}
340
- function updateCostDisplay(t){var el=document.getElementById("costDisplay");if(!selectedModelId||!t||!modelPricing[selectedModelId]){el.classList.add("hidden");return;}var p=modelPricing[selectedModelId];if(typeof p.input!=='number'){el.classList.add("hidden");return;}el.textContent="~$"+((p.input||0)*t+(p.output||0)*(t*0.3)).toFixed(4);el.classList.remove("hidden");}
341
-
342
- function clearOldConversations(){
343
- showConfirmDialog("Delete all conversations except the current one?",function(confirmed){if(!confirmed)return;
344
- var cur=getCurrentChat(),curId=cur?cur.id:null;var keep=cur?[{id:cur.id,title:cur.title,model:cur.model,messages:cur.messages,createdAt:cur.createdAt}]:[];
345
- var RS=window.RightSidebar;
346
- if(RS){RS._files=RS._files.filter(function(f){return f.chatId===curId||keep.some(function(k){return k.id===f.chatId;});});RS._order=RS._order.filter(function(id){return RS._files.some(function(f){return f.id===id;});});}
347
- if(DB._ready){
348
- conversations.forEach(function(c){if(c.id!==curId){DB.deleteConversation(c.id);DB.deleteConversationFiles(c.id);}});
349
- conversations.forEach(function(c){if(c.id!==curId){try{localStorage.removeItem("chatpad_files_"+c.id);}catch(ex){}}});
350
- }
351
- conversations=keep;saveConversations();renderChatHistory();if(RS)RS.render();showToast("Cleared");
352
- });
353
- }
354
-
355
- function isMobile(){return window.innerWidth<768;}
356
- function openLeftSidebar(){if(!isMobile())return;document.getElementById("leftSidebar").classList.add("open");document.getElementById("leftSidebarOverlay").classList.add("show");document.body.style.overflow="hidden";}
357
- function closeLeftSidebar(){document.getElementById("leftSidebar").classList.remove("open");document.getElementById("leftSidebarOverlay").classList.remove("show");document.body.style.overflow="";}
358
- function isTablet(){return window.innerWidth<1024;}
359
- function closeRightSidebar(){if(!isTablet())return;document.getElementById("rightSidebar").classList.remove("open");document.getElementById("rightSidebar").classList.add("collapsed");document.getElementById("rsBackdrop").classList.remove("show");if(window.RightSidebar)window.RightSidebar._visible=false;var t=document.getElementById("rightSidebarToggle");if(t)t.classList.remove("open");}
360
-
361
- function openSettings(){closeLeftSidebar();document.getElementById("settingsModal").classList.add("show");document.getElementById("apiKeyModal").value=API_KEY;try{document.getElementById("sysPromptModal").value=_savedSysPrompt||"";}catch(ex){}var s=document.getElementById("stepSlider");s.value=MAX_STEPS>=999?50:MAX_STEPS;document.getElementById("stepValue").textContent=MAX_STEPS>=999?"∞":MAX_STEPS;document.getElementById("unlimitedSteps").checked=(MAX_STEPS>=999);updateKeyStatusModal();var modeEl=document.getElementById("storageModeSelect");if(modeEl){modeEl.value=storageMode;onStorageModeChange();}var ctxT=document.getElementById("contextTurnsSlider");if(ctxT){ctxT.value=MAX_CONTEXT_TURNS;document.getElementById("contextTurnsValue").textContent=MAX_CONTEXT_TURNS;}var ctxF=document.getElementById("contextFilesSlider");if(ctxF){ctxF.value=MAX_CONTEXT_FILES;document.getElementById("contextFilesValue").textContent=MAX_CONTEXT_FILES;}var ml=document.getElementById("modulesLocationInput");if(ml)ml.value=MODULES_LOCATION;}
362
- function closeSettings(){document.getElementById("settingsModal").classList.remove("show");}
363
- function updateKeyStatusModal(){var el=document.getElementById("keyStatusModal");if(API_KEY&&API_KEY.indexOf("sk-or-")===0)el.innerHTML='<i class="fas fa-circle" style="color:#6ee7b7"></i>';else if(API_KEY)el.innerHTML='<i class="fas fa-circle" style="color:#facc15"></i>';else el.innerHTML='<i class="fas fa-circle" style="color:#6b7280"></i>';}
364
-
365
- function syncApiKey(){API_KEY=document.getElementById("apiKeyModal").value.trim();if(storageMode==='localStorage'){try{localStorage.setItem("huggingbot_api_key",API_KEY);}catch(ex){}}else if(storageMode==='indexedDB'&&DB._ready){DB.setSetting("api_key",API_KEY);}updateKeyStatusModal();}
366
- function saveSysPrompt(){_savedSysPrompt=document.getElementById("sysPromptModal").value.trim();if(storageMode==='localStorage'){try{localStorage.setItem("huggingbot_sys_prompt",_savedSysPrompt);}catch(ex){}}else if(storageMode==='indexedDB'&&DB._ready){DB.setSetting("sys_prompt",_savedSysPrompt);}}
367
- function saveModulesLocation(){var ml=document.getElementById("modulesLocationInput");if(!ml)return;MODULES_LOCATION=ml.value.trim();if(storageMode==='localStorage'){try{localStorage.setItem("huggingbot_modules_location",MODULES_LOCATION);}catch(ex){}}else if(storageMode==='indexedDB'&&DB._ready){DB.setSetting("modules_location",MODULES_LOCATION);}}
368
- function saveSettings(){var oldMode=storageMode;syncApiKey();saveSysPrompt();saveModulesLocation();MAX_STEPS=document.getElementById("unlimitedSteps").checked?999:(parseInt(document.getElementById("stepSlider").value)||10);MAX_CONTEXT_TURNS=parseInt(document.getElementById("contextTurnsSlider").value)||5;MAX_CONTEXT_FILES=parseInt(document.getElementById("contextFilesSlider").value)||5;var modeEl=document.getElementById("storageModeSelect");if(modeEl)storageMode=modeEl.value;if(storageMode==='localStorage'){try{localStorage.setItem("huggingbot_max_steps",String(MAX_STEPS));localStorage.setItem("huggingbot_context_turns",String(MAX_CONTEXT_TURNS));localStorage.setItem("huggingbot_context_files",String(MAX_CONTEXT_FILES));localStorage.setItem("huggingbot_storage_mode","localStorage");}catch(ex){}}else if(storageMode==='indexedDB'&&DB._ready){DB.setSetting("max_steps",String(MAX_STEPS));DB.setSetting("context_turns",String(MAX_CONTEXT_TURNS));DB.setSetting("context_files",String(MAX_CONTEXT_FILES));DB.setSetting("storage_mode","indexedDB");}closeSettings();if(oldMode!==storageMode){showToast("Switching to "+storageMode+"...");setTimeout(function(){forceReloadConversations();},100);}else{showToast("Settings saved");}}
369
- function updateStepDisplay(){var v=parseInt(document.getElementById("stepSlider").value);document.getElementById("stepValue").textContent=v;document.getElementById("unlimitedSteps").checked=false;MAX_STEPS=v;}
370
- function toggleUnlimitedSteps(){if(document.getElementById("unlimitedSteps").checked){MAX_STEPS=999;document.getElementById("stepSlider").value=999;document.getElementById("stepValue").textContent="∞";}else{MAX_STEPS=10;document.getElementById("stepSlider").value=10;document.getElementById("stepValue").textContent="10";}if(storageMode==='localStorage'){try{localStorage.setItem("huggingbot_max_steps",String(MAX_STEPS));}catch(ex){}}else if(storageMode==='indexedDB'&&DB._ready){DB.setSetting("max_steps",String(MAX_STEPS));}}
371
- function updateContextTurnsDisplay(){var v=parseInt(document.getElementById("contextTurnsSlider").value);document.getElementById("contextTurnsValue").textContent=v;MAX_CONTEXT_TURNS=v;}
372
- function updateContextFilesDisplay(){var v=parseInt(document.getElementById("contextFilesSlider").value);document.getElementById("contextFilesValue").textContent=v;MAX_CONTEXT_FILES=v;}
373
- function getSystemPrompt(){if(_savedSysPrompt)return _savedSysPrompt;if(storageMode==='localStorage'){try{var v=localStorage.getItem("huggingbot_sys_prompt")||"";_savedSysPrompt=v;return v;}catch(ex){return "";}}if(DB._ready){return _savedSysPrompt||"";}return "";}
374
- function onStorageModeChange(){var el=document.getElementById("storageModeSelect");var label=document.getElementById("storageModeLabel");if(!el||!label)return;var mode=el.value;if(mode==="indexedDB"&&!DB._ready){label.textContent="⚠ Not available";label.style.color="#f87171";return;}label.textContent=mode==="indexedDB"?"✓ Using IndexedDB":"✓ Using localStorage";label.style.color="#6ee7b7";}
375
-
376
- function trimContext(){
377
- if(!currentChatId)return;
378
- var chat=getCurrentChat();if(!chat||!chat.messages)return;
379
- if(chat.messages.length>MAX_CONTEXT_TURNS*2){
380
- var keep=MAX_CONTEXT_TURNS*2;
381
- var firstUserIdx=-1;
382
- for(var i=0;i<chat.messages.length;i++){
383
- if(chat.messages[i].role==="user"){firstUserIdx=i;break;}
384
- }
385
- if(firstUserIdx>=0&&firstUserIdx<chat.messages.length-keep){
386
- var tail=chat.messages.slice(-(keep-1));
387
- chat.messages=[chat.messages[firstUserIdx]].concat(tail);
388
- } else {
389
- chat.messages=chat.messages.slice(-keep);
390
- }
391
- chat.updatedAt=new Date().toISOString();
392
- }
393
- var RS=window.RightSidebar;
394
- if(RS){
395
- var chatFiles=RS._getFilesForChat(currentChatId);
396
- if(chatFiles.length>MAX_CONTEXT_FILES){
397
- chatFiles.sort(function(a,b){return (a.addedAt||0)-(b.addedAt||0);});
398
- var toRemove=chatFiles.slice(0,chatFiles.length-MAX_CONTEXT_FILES);
399
- for(var i=0;i<toRemove.length;i++){RS.removeFile(toRemove[i].id);}
400
- }
401
- }
402
- }
403
-
404
- function newChat(){closeLeftSidebar();if(currentChatId){var c=getCurrentChat();if(c&&c.messages&&c.messages.length>0)saveConversations();}
405
- var chat={id:"chat_"+Date.now(),title:"New Chat",model:selectedModelId||"",messages:[],createdAt:new Date().toISOString()};
406
- conversations.unshift(chat);saveConversations();
407
- var RS=window.RightSidebar;
408
- if(RS){RS._files=RS._files.filter(function(f){return f.chatId!==currentChatId;});RS._order=[];RS._active=null;RS.render();}
409
- loadChat(chat.id);}
410
-
411
- function loadChat(id){if(id===currentChatId)return;if(currentChatId)saveConversations();currentChatId=id;closeLeftSidebar();var chat=getCurrentChat();if(!chat)return;
412
- var RS=window.RightSidebar;
413
- if(RS){RS._order=[];RS._active=null;}
414
- if(chat.model){var found=null;for(var i=0;i<AVAILABLE_MODELS.length;i++)if(AVAILABLE_MODELS[i].id===chat.model){found=AVAILABLE_MODELS[i];break;}var input=document.getElementById("modelSearchInput");if(found){input.value=found.name;input.dataset.modelId=found.id;selectedModelId=found.id;document.getElementById("currentModelHeader").textContent=found.name;}else{input.value=chat.model;input.dataset.modelId=chat.model;selectedModelId=chat.model;document.getElementById("currentModelHeader").textContent=chat.model;}}
415
- if(!isProcessing)setProcessingUI(false);
416
- renderMessages(chat.messages);renderChatHistory();updateTokenDisplay();
417
- document.getElementById("scrollFab").classList.remove("show");
418
- if(RS)RS.loadForChat(currentChatId);}
419
-
420
- function forceReloadConversations(){
421
- var curId=currentChatId;
422
- if(storageMode==="indexedDB"&&DB._ready){
423
- DB.getAllSettings().then(function(settings){
424
- if(settings.api_key){API_KEY=settings.api_key;document.getElementById("apiKeyModal").value=API_KEY;updateKeyStatusModal();}
425
- if(settings.sys_prompt){_savedSysPrompt=settings.sys_prompt;document.getElementById("sysPromptModal").value=_savedSysPrompt;}
426
- if(settings.max_steps){MAX_STEPS=parseInt(settings.max_steps)||10;var s=document.getElementById("stepSlider");if(s)s.value=MAX_STEPS>=999?50:MAX_STEPS;var sv=document.getElementById("stepValue");if(sv)sv.textContent=MAX_STEPS>=999?"∞":MAX_STEPS;var uc=document.getElementById("unlimitedSteps");if(uc)uc.checked=(MAX_STEPS>=999);}
427
- if(settings.context_turns){MAX_CONTEXT_TURNS=parseInt(settings.context_turns)||5;var ct=document.getElementById("contextTurnsSlider");if(ct)ct.value=MAX_CONTEXT_TURNS;var ctv=document.getElementById("contextTurnsValue");if(ctv)ctv.textContent=MAX_CONTEXT_TURNS;}
428
- if(settings.context_files){MAX_CONTEXT_FILES=parseInt(settings.context_files)||5;var cf=document.getElementById("contextFilesSlider");if(cf)cf.value=MAX_CONTEXT_FILES;var cfv=document.getElementById("contextFilesValue");if(cfv)cfv.textContent=MAX_CONTEXT_FILES;}
429
- if(settings.modules_location){MODULES_LOCATION=settings.modules_location;var ml=document.getElementById("modulesLocationInput");if(ml)ml.value=MODULES_LOCATION;}
430
- }).catch(function(){});
431
- DB.getAllConversations().then(function(dbChats){
432
- conversations=dbChats||[];
433
- conversations.sort(function(a,b){return getChatSortTime(b)-getChatSortTime(a);});
434
- var found=conversations.some(function(c){return c.id===curId;});
435
- if(found)loadChat(curId);
436
- else if(conversations.length>0)loadChat(conversations[0].id);
437
- else newChat();
438
- showToast("Loaded "+conversations.length+" conversations from IndexedDB");
439
- }).catch(function(){showToast("Failed to load from IndexedDB");});
440
- } else {
441
- try{var s=localStorage.getItem(STORAGE_KEY);if(s){var p=JSON.parse(s);if(Array.isArray(p)&&p.length>0){conversations=p;}else{conversations=[];}}else{conversations=[];}}catch(ex){conversations=[];}
442
- try{var k=localStorage.getItem("huggingbot_api_key");if(k){API_KEY=k;document.getElementById("apiKeyModal").value=k;updateKeyStatusModal();}}catch(ex){}
443
- try{var sp=localStorage.getItem("huggingbot_sys_prompt");if(sp){_savedSysPrompt=sp;document.getElementById("sysPromptModal").value=sp;}}catch(ex){}
444
- try{var ms=localStorage.getItem("huggingbot_max_steps");if(ms){MAX_STEPS=parseInt(ms)||10;var s=document.getElementById("stepSlider");if(s)s.value=MAX_STEPS>=999?50:MAX_STEPS;var sv=document.getElementById("stepValue");if(sv)sv.textContent=MAX_STEPS>=999?"∞":MAX_STEPS;var uc=document.getElementById("unlimitedSteps");if(uc)uc.checked=(MAX_STEPS>=999);}}catch(ex){}
445
- try{var ct=localStorage.getItem("huggingbot_context_turns");if(ct){MAX_CONTEXT_TURNS=parseInt(ct)||5;var cts=document.getElementById("contextTurnsSlider");if(cts)cts.value=MAX_CONTEXT_TURNS;var ctv=document.getElementById("contextTurnsValue");if(ctv)ctv.textContent=MAX_CONTEXT_TURNS;}}catch(ex){}
446
- try{var cf=localStorage.getItem("huggingbot_context_files");if(cf){MAX_CONTEXT_FILES=parseInt(cf)||5;var cfs=document.getElementById("contextFilesSlider");if(cfs)cfs.value=MAX_CONTEXT_FILES;var cfv=document.getElementById("contextFilesValue");if(cfv)cfv.textContent=MAX_CONTEXT_FILES;}}catch(ex){}
447
- try{var ml=localStorage.getItem("huggingbot_modules_location");if(ml){MODULES_LOCATION=ml;var mli=document.getElementById("modulesLocationInput");if(mli)mli.value=ml;}}catch(ex){}
448
- var found=conversations.some(function(c){return c.id===curId;});
449
- if(found)loadChat(curId);
450
- else if(conversations.length>0)loadChat(conversations[0].id);
451
- else newChat();
452
- showToast("Loaded "+conversations.length+" conversations from localStorage");
453
- }
454
- }
455
-
456
- function deleteCurrentChat(){if(!currentChatId){showToast("No chat");return;}
457
- showConfirmDialog("Delete this conversation forever?",function(confirmed){if(!confirmed)return;
458
- var idx=-1;for(var i=0;i<conversations.length;i++){if(conversations[i].id===currentChatId){idx=i;break;}}if(idx===-1)return;
459
- var RS=window.RightSidebar;
460
- if(RS){RS._files=RS._files.filter(function(f){return f.chatId!==currentChatId;});RS._order=[];RS._active=null;}
461
- if(DB._ready){DB.deleteConversation(currentChatId);DB.deleteConversationFiles(currentChatId);}
462
- conversations.splice(idx,1);saveConversations();
463
- if(conversations.length>0)loadChat(conversations[0].id);else newChat();showToast("Deleted");
464
- });
465
- }
466
-
467
- // ===== MODEL DROPDOWN =====
468
- function filterModelDropdown(){
469
- var dropdown=document.getElementById("modelDropdown");
470
- var input=document.getElementById("modelSearchInput");
471
- if(!dropdown||!input)return;
472
- var q=input.value.toLowerCase().trim();
473
- dropdown.innerHTML="";
474
- if(!q){dropdown.classList.remove("show");return;}
475
- var matches=[],exactMatch=null;
476
- for(var i=0;i<AVAILABLE_MODELS.length;i++){
477
- var m=AVAILABLE_MODELS[i];
478
- if(m.id.toLowerCase().indexOf(q)!==-1||m.name.toLowerCase().indexOf(q)!==-1){
479
- matches.push(m);
480
- if(m.id===input.dataset.modelId||m.name.toLowerCase()===q)exactMatch=m;
481
- }
482
- }
483
- if(matches.length===0){dropdown.classList.remove("show");return;}
484
- if(matches.length===1&&exactMatch){dropdown.classList.remove("show");return;}
485
- dropdown.classList.add("show");
486
- for(var i=0;i<matches.length;i++){
487
- var item=document.createElement("div");
488
- item.className="model-dropdown-item"+(matches[i].id===selectedModelId?" active":"");
489
- item.textContent=matches[i].name;
490
- var provider=matches[i].id.split("/")[0]||"";
491
- var ctx=matches[i].context_length?Math.round(matches[i].context_length/1000)+"K":"";
492
- item.innerHTML=matches[i].name+' <span class="model-provider">'+provider+'</span>'+(ctx?'<span class="model-context">'+ctx+'</span>':'');
493
- item.onclick=(function(mid){return function(){selectModelFromDropdown(mid);};})(matches[i].id);
494
- dropdown.appendChild(item);
495
- }
496
- modelIndex=0;highlightModel(dropdown.querySelectorAll(".model-dropdown-item"));
497
- }
498
- function closeModelDropdown(){var dropdown=document.getElementById("modelDropdown");if(dropdown)dropdown.classList.remove("show");}
499
- function onModelKeydown(e){
500
- var dropdown=document.getElementById("modelDropdown");
501
- if(!dropdown||!dropdown.classList.contains("show"))return;
502
- var items=dropdown.querySelectorAll(".model-dropdown-item");
503
- if(items.length===0)return;
504
- if(e.key==="ArrowDown"){e.preventDefault();modelIndex=(modelIndex+1)%items.length;highlightModel(items);}
505
- else if(e.key==="ArrowUp"){e.preventDefault();modelIndex=(modelIndex-1+items.length)%items.length;highlightModel(items);}
506
- else if(e.key==="Enter"){e.preventDefault();if(items[modelIndex]){var md=items[modelIndex].textContent;var mid=null;for(var i=0;i<AVAILABLE_MODELS.length;i++){if(AVAILABLE_MODELS[i].name===md){mid=AVAILABLE_MODELS[i].id;break;}}if(mid)selectModelFromDropdown(mid);}}
507
- else if(e.key==="Escape"){closeModelDropdown();}
508
- }
509
- function highlightModel(items){for(var i=0;i<items.length;i++)items[i].classList.toggle("active",i===modelIndex);if(items[modelIndex])items[modelIndex].scrollIntoView({block:"nearest"});}
510
- function selectModelFromDropdown(id){var model=null;for(var i=0;i<AVAILABLE_MODELS.length;i++)if(AVAILABLE_MODELS[i].id===id){model=AVAILABLE_MODELS[i];break;}if(!model)return;var input=document.getElementById("modelSearchInput");input.value=model.name;input.dataset.modelId=id;selectedModelId=id;closeModelDropdown();document.getElementById("currentModelHeader").textContent=model.name;var chat=getCurrentChat();if(chat){chat.model=id;saveConversations();}updateTokenDisplay();}
511
-
512
- // ===== CHAT HISTORY =====
513
- function getChatSortTime(chat){
514
- if(chat.updatedAt)return new Date(chat.updatedAt).getTime();
515
- if(chat.messages&&chat.messages.length>0){
516
- var last=chat.messages[chat.messages.length-1];
517
- if(last.timestamp)return new Date(last.timestamp).getTime();
518
- }
519
- return new Date(chat.createdAt||0).getTime();
520
- }
521
-
522
- function renderChatHistory(){
523
- var container=document.getElementById("chatHistory"),qInput=document.getElementById("convSearch");
524
- var q=qInput?qInput.value.toLowerCase().trim():"";
525
- var sorted=conversations.slice().sort(function(a,b){return getChatSortTime(b)-getChatSortTime(a);});
526
- var filtered=[];
527
- for(var i=0;i<sorted.length;i++){var c=sorted[i];if(!q){filtered.push(c);continue;}if(c.title.toLowerCase().indexOf(q)!==-1){filtered.push(c);continue;}var found=false;for(var j=0;j<c.messages.length;j++){if(c.messages[j].content&&c.messages[j].content.toLowerCase().indexOf(q)!==-1){found=true;break;}}if(found)filtered.push(c);}
528
- if(filtered.length===0){container.innerHTML='<div class="text-xs text-gray-500 text-center py-4">No conversations found</div>';return;}
529
- var html="";
530
- for(var i=0;i<filtered.length;i++){var c=filtered[i],isActive=c.id===currentChatId;
531
- var timeLabel="";
532
- var sortTime=getChatSortTime(c);
533
- if(sortTime){var diff=Date.now()-sortTime;if(diff<60000)timeLabel="Just now";else if(diff<3600000)timeLabel=Math.floor(diff/60000)+"m ago";else if(diff<86400000)timeLabel=Math.floor(diff/3600000)+"h ago";else timeLabel=new Date(sortTime).toLocaleDateString();}
534
- else{timeLabel=new Date(c.createdAt).toLocaleDateString();}
535
- var RS=window.RightSidebar;
536
- var fc=RS?RS._getFileCountForChat(c.id):0;var fb=fc>0?' <span style="font-size:.55rem;color:#6ee7b7"><i class="fas fa-paperclip"></i> '+fc+'</span>':'';
537
- html+='<div class="conv-item px-4 py-3 rounded-2xl cursor-pointer '+(isActive?'bg-gray-700/50 border border-gray-600':'hover:bg-gray-800')+'" data-chat-id="'+c.id+'"><div class="line-clamp-1 text-sm flex items-center gap-1">'+sanitizeHTML(c.title)+fb+'</div><div class="text-xs text-gray-500 flex items-center justify-between"><span>'+timeLabel+'</span></div></div>';}
538
- container.innerHTML=html;
539
- var items=container.querySelectorAll(".conv-item");
540
- for(var i=0;i<items.length;i++){(function(cid){items[i].addEventListener("click",function(){loadChat(cid);});})(filtered[i].id);}
541
- }
542
-
543
- // ===== MODULE SYSTEM =====
544
- function renderModuleList(){var el=document.getElementById("moduleList");if(!el)return;var html="";for(var id in MODULE_REGISTRY){var mod=MODULE_REGISTRY[id];var state=MODULE_STATES[id];if(!state)continue;var isOn=state.enabled;var modName=mod.name||id;var modDesc=mod.description||"";html+='<div class="module-item"><span class="mod-name" title="'+sanitizeHTML(modDesc)+'">'+sanitizeHTML(modName)+'</span><span class="mod-status" style="color:'+(isOn?'#6ee7b7':'#6b7280')+'">'+(isOn?'ON':'OFF')+'</span><div class="mod-toggle'+(isOn?' on':'')+'" onclick="ModuleSystem.toggleModule(\''+id+'\')"></div></div>';}el.innerHTML=html;updateActiveModuleCount();}
545
- var ModuleSystem={register:function(id,api){if(MODULE_REGISTRY[id])return;MODULE_REGISTRY[id]=api;MODULE_STATES[id]={enabled:true,loaded:true,status:"active"};if(api.tools)api.tools.forEach(function(t){t._moduleId=id;});renderModuleList();rebuildCoreTools();},handleToolCall:async function(tn,args,tcid){for(var id in MODULE_REGISTRY){var mod=MODULE_REGISTRY[id];if(!MODULE_STATES[id]||!MODULE_STATES[id].enabled)continue;if(mod.handleToolCall&&typeof mod.handleToolCall==="function"){var result=await mod.handleToolCall(tn,args,tcid);if(result!==undefined&&result!==null)return result;}}return null;},getToolDescriptions:function(){var lines=[];for(var id in MODULE_REGISTRY){var mod=MODULE_REGISTRY[id];if(!MODULE_STATES[id]||!MODULE_STATES[id].enabled)continue;if(mod.description)lines.push("- **"+mod.name+"**: "+mod.description);if(mod.tools)for(var i=0;i<mod.tools.length;i++){var t=mod.tools[i];if(t.function&&t.function.description)lines.push(" - `"+t.function.name+"`: "+t.function.description);}}return lines.join("\n");},toggleModule:function(id){if(!MODULE_STATES[id])return;MODULE_STATES[id].enabled=!MODULE_STATES[id].enabled;renderModuleList();rebuildCoreTools();updateActiveModuleCount();showToast((MODULE_STATES[id].enabled?"Enabled":"Disabled")+": "+(MODULE_REGISTRY[id].name||id));},
546
- // 👇 Context and post-response hooks (used by wiki module for auto-injection and build loop)
547
- getContext:async function(userMessage,sessionInfo){return '';},
548
- onResponse:async function(userMessage,aiResponse,toolCalls,sessionInfo){}};
549
- function rebuildCoreTools(){CORE_TOOLS=[SELF_EVOLUTION_TOOL];for(var id in MODULE_REGISTRY){var mod=MODULE_REGISTRY[id];if(!MODULE_STATES[id]||!MODULE_STATES[id].enabled)continue;if(mod.tools)CORE_TOOLS=CORE_TOOLS.concat(mod.tools);}}
550
- function toggleModulesAccordion(){modulesAccordionOpen=!modulesAccordionOpen;var body=document.getElementById("modulesAccordionBody"),arrow=document.getElementById("modulesAccordionArrow");if(modulesAccordionOpen){body.style.maxHeight="20vh";body.classList.add("open");arrow.classList.add("open");}else{body.style.maxHeight="0";body.classList.remove("open");arrow.classList.remove("open");}}
551
- function updateActiveModuleCount(){var el=document.getElementById("activeModuleCount");if(!el)return;var count=0;for(var id in MODULE_STATES)if(MODULE_STATES[id].enabled)count++;el.textContent=count+" active";}
552
-
553
- var SELF_EVOLUTION_TOOL={type:"function",function:{name:"evolve_self",description:"Read, analyze, diff, refactor, write, or perform LINE-LEVEL edits on source code or ScratchPad files. The edit buffer is tracked by _editTarget (filename) and _editContent (content). Use load_source to load the CURRENTLY RUNNING source code from browser memory into ScratchPad. Use set_target_file to select a ScratchPad file as the active target. Use read to view the active buffer (always returns file status). Use write_file to save versioned copies (old versions are automatically preserved as .v1, .v2, etc. — files are NEVER deleted). After write_file, that file becomes the new target. Use edit_lines, insert_lines, delete_lines, append_lines for line-level edits. Each result ends with a fileStatusContext() line showing where the next edit lands.",parameters:{type:"object",properties:{action:{type:"string",enum:["load_source","read","analyze","diff","refactor","write","write_source","write_file","read_lines","edit_lines","insert_lines","delete_lines","append_lines","search_code","list_files","read_file","set_target_file"],description:"What to do. write/write_file accept new_code OR content. All results include fileStatusContext()."},description:{type:"string"},new_code:{type:"string"},new_filename:{type:"string"},target_filename:{type:"string"},start_line:{type:"number"},end_line:{type:"number"},line_number:{type:"number"},content:{type:"string"},pattern:{type:"string"},is_regex:{type:"boolean"}},required:["action","description"]}}};CORE_TOOLS=[SELF_EVOLUTION_TOOL];
554
-
555
- async function loadExternalModules(){try{var basePath='./modules/';if(MODULES_LOCATION&&MODULES_LOCATION.trim()!==''){var loc=MODULES_LOCATION.trim();if(loc.indexOf('://')!==-1||loc.indexOf('//')===0){basePath=loc.endsWith('/')?loc:loc+'/';}else{basePath=loc.endsWith('/')?loc:loc+'/';}}var manifestSrc=basePath+'modules_manifest.js';await new Promise(function(resolve,reject){var s=document.createElement('script');s.src=manifestSrc;s.async=false;s.onload=resolve;s.onerror=reject;document.body.appendChild(s);});var manifest=window.__CHATSEED_MODULES_MANIFEST;if(!manifest||!manifest.modules||!manifest.modules.length){loadFallbackModules();return;}var mods=manifest.modules,loaded=0;for(var i=0;i<mods.length;i++){var info=mods[i];if(MODULE_LOADED_FILES[info.id])continue;MODULE_LOADED_FILES[info.id]=true;try{var script=document.createElement('script');script.src=basePath+info.file;script.async=false;script.setAttribute('data-module',info.id);await new Promise(function(resolve,reject){script.onload=resolve;script.onerror=reject;document.body.appendChild(script);});loaded++;}catch(ex){}}renderModuleList();updateActiveModuleCount();if(loaded>0)showToast('Loaded '+loaded+' modules');else loadFallbackModules();}catch(ex){loadFallbackModules();}}
556
- function reloadModules(){showToast('Reloading...');for(var id in MODULE_REGISTRY){document.querySelectorAll('style[data-module="'+id+'"]').forEach(function(s){s.remove();});document.querySelectorAll('script[data-module="'+id+'"]').forEach(function(s){s.remove();});}MODULE_REGISTRY={};MODULE_STATES={};MODULE_LOADED_FILES={};CORE_TOOLS=[SELF_EVOLUTION_TOOL];renderModuleList();loadExternalModules();}
557
-
558
- function loadFallbackModules(){
559
- ModuleSystem.register("search-web",{name:"Web Search",description:"Search the internet.",tools:[{type:"function",function:{name:"search_web",description:"Search the internet. Returns titles, snippets, and URLs.",parameters:{type:"object",properties:{query:{type:"string"},max_results:{type:"number",default:5},source:{type:"string",enum:["auto","web","wikipedia","news","reddit"],default:"auto"}},required:["query"]}}}],handleToolCall:async function(tn,args){if(tn!=="search_web")return null;try{var q=args.query,mx=Math.min(Math.max(parseInt(args.max_results)||5,1),10),source=args.source||"auto",allResults=[];if(source==="auto"||source==="web"||source==="wikipedia"){try{var wr=await fetch("https://en.wikipedia.org/w/api.php?action=query&list=search&srsearch="+encodeURIComponent(q)+"&format=json&srlimit="+mx+"&origin=*");if(wr.ok){var wd=await wr.json();if(wd.query&&wd.query.search){wd.query.search.forEach(function(s){allResults.push({title:s.title,snippet:s.snippet.replace(/<\/?[^>]+(>|$)/g,""),url:"https://en.wikipedia.org/wiki/"+encodeURIComponent(s.title.replace(/ /g,"_")),source:"Wikipedia"});});}}}catch(ex){}}if(source==="auto"||source==="web"){try{var dr=await fetch("https://api.duckduckgo.com/?q="+encodeURIComponent(q)+"&format=json&no_html=1&skip_disambig=1&t=chatseed");if(dr.ok){var dd=await dr.json();if(dd.AbstractText)allResults.push({title:dd.Heading||"About",snippet:dd.AbstractText,url:dd.AbstractURL||"",source:"DuckDuckGo"});}}catch(ex){}}if(source==="auto"||source==="reddit"||source==="news"){try{var rr=await fetch("https://www.reddit.com/search.json?q="+encodeURIComponent(q)+"&limit="+mx+"&sort=relevance&t=all",{headers:{"User-Agent":"Mozilla/5.0 ChatSeed/1.0"}});if(rr.ok){var rd=await rr.json();if(rd.data&&rd.data.children){rd.data.children.forEach(function(c){if(c.data&&c.data.title)allResults.push({title:"[Reddit] "+c.data.title,snippet:(c.data.selftext||c.data.url||"").substring(0,200).replace(/\n/g," "),url:"https://www.reddit.com"+c.data.permalink,source:"Reddit"});});}}}catch(ex){}}var seen={},deduped=[];allResults.forEach(function(item){if(!item.title)return;var key=(item.url||item.snippet||item.title).substring(0,80);if(!seen[key]){seen[key]=true;deduped.push(item);}});var out=["## Search Results: \""+q+"\"",""];if(deduped.length===0){out.push("*No results found.*");}else{deduped.slice(0,mx).forEach(function(r,i){out.push("### "+(i+1)+". "+(r.title||""));if(r.snippet)out.push("> "+r.snippet);if(r.url)out.push("Link: "+r.url);out.push("");});}return out.join("\n");}catch(ex){return "## Search error: "+ex.message;}}});
560
- ModuleSystem.register("calculator",{name:"Calculator",description:"Precise calculations",tools:[{type:"function",function:{name:"calculate",description:"Evaluate a math expression",parameters:{type:"object",properties:{expression:{type:"string"}},required:["expression"]}}}],handleToolCall:async function(tn,args){if(tn!=="calculate")return null;try{var e=args.expression;var p=e.replace(/\^/g,"**").replace(/\bpi\b/gi,"("+Math.PI+")").replace(/\bsin\(/g,"Math.sin(").replace(/\bcos\(/g,"Math.cos(").replace(/\btan\(/g,"Math.tan(").replace(/\bsqrt\(/g,"Math.sqrt(").replace(/\blog\(/g,"Math.log10(").replace(/\bln\(/g,"Math.log(").replace(/\babs\(/g,"Math.abs(");return""+e+" = "+Function('"use strict";return ('+p+')')()+"";}catch(ex){return "Error: "+ex.message;}}});
561
- ModuleSystem.register("image-gen",{name:"Image Generation",description:"Generate images from text prompts.",tools:[{type:"function",function:{name:"generate_image",description:"Generate an image from a text description.",parameters:{type:"object",properties:{prompt:{type:"string"},width:{type:"number",default:512},height:{type:"number",default:512}},required:["prompt"]}}}],handleToolCall:async function(tn,args){if(tn!=="generate_image")return null;var w=parseInt(args.width)||512,h=parseInt(args.height)||512;return"![Generated: "+args.prompt+"](https://image.pollinations.ai/prompt/"+encodeURIComponent(args.prompt)+"?width="+w+"&height="+h+"&nologo=true)"}});
562
- ModuleSystem.register("qr-tools",{name:"QR Code",description:"Generate QR codes.",tools:[{type:"function",function:{name:"generate_qr",description:"Generate a QR code.",parameters:{type:"object",properties:{data:{type:"string"},label:{type:"string"},size:{type:"number",default:250}},required:["data"]}}}],handleToolCall:async function(tn,args){if(tn!=="generate_qr")return null;var s=Math.min(Math.max(parseInt(args.size)||250,100),500);return"![QR Code](https://api.qrserver.com/v1/create-qr-code/?size="+s+"x"+s+"&data="+encodeURIComponent(args.data)+")"}});
563
- ModuleSystem.register("weather",{name:"Weather",description:"Get current weather.",tools:[{type:"function",function:{name:"get_weather",description:"Get current weather.",parameters:{type:"object",properties:{location:{type:"string"},forecast_days:{type:"number",default:3}},required:["location"]}}}],handleToolCall:async function(tn,args){if(tn!=="get_weather")return null;try{var r=await fetch("https://wttr.in/"+encodeURIComponent(args.location)+"?format=%C+%t+%w+%h&m");if(r.ok)return"Weather for "+args.location+": "+(await r.text());return"Weather unavailable";}catch(ex){return"Weather error: "+ex.message;}}});
564
- ModuleSystem.register("news",{name:"News Headlines",description:"Fetch latest news.",tools:[{type:"function",function:{name:"get_news",description:"Get latest news.",parameters:{type:"object",properties:{query:{type:"string"},max_results:{type:"number",default:5}},required:[]}}}],handleToolCall:async function(tn,args){if(tn!=="get_news")return null;try{var r=await fetch("https://api.allorigins.win/raw?url="+encodeURIComponent("https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml"));if(!r.ok)return"News unavailable";var xml=await r.text();var items=xml.match(/<item>[\s\S]*?<\/item>/g)||[];var out=["## News Headlines"];var limit=Math.min(parseInt(args.max_results)||5,items.length);for(var i=0;i<limit;i++){var title=(items[i].match(/<title>([^<]*)<\/title>/)||["",""])[1];var link=(items[i].match(/<link>([^<]*)<\/link>/)||["",""])[1];if(title)out.push((i+1)+". "+title.replace(/<!\[CDATA\[|\]\]>/g,""));if(link)out.push(" "+link);}return out.join("\n");}catch(ex){return"News error: "+ex.message;}}});
565
- ModuleSystem.register("dictionary",{name:"Dictionary",description:"Look up word definitions.",tools:[{type:"function",function:{name:"define_word",description:"Get definition for any word.",parameters:{type:"object",properties:{word:{type:"string"}},required:["word"]}}}],handleToolCall:async function(tn,args){if(tn!=="define_word")return null;try{var r=await fetch("https://api.dictionaryapi.dev/api/v2/entries/en/"+encodeURIComponent(args.word));if(!r.ok)return"Word not found";var d=await r.json();var entry=d[0];var out=["## "+entry.word,""];if(entry.phonetic)out.push("Pronunciation: `"+entry.phonetic+"`");if(entry.meanings){entry.meanings.forEach(function(m){if(m.partOfSpeech)out.push("*"+m.partOfSpeech+"*");if(m.definitions){m.definitions.slice(0,3).forEach(function(def){out.push("- "+def.definition);if(def.example)out.push(" > \""+def.example+"\"");});}});}return out.join("\n");}catch(ex){return"Dictionary error: "+ex.message;}}});
566
- renderModuleList();updateActiveModuleCount();showToast('Using built-in fallback modules (7/7 loaded)');}
567
-
568
- // ===== SEND MESSAGE =====
569
- async function sendMessage(){if(isProcessing)return;var input=document.getElementById("userInput"),text=input.value.trim();if(!text||!currentChatId)return;var chat=getCurrentChat();if(!chat)return;
570
- chat.messages.push({role:"user",content:text,timestamp:getTimeStr()});var uc=0;for(var i=0;i<chat.messages.length;i++){if(chat.messages[i].role==="user")uc++;}if(uc===1)chat.title=text.slice(0,50)+(text.length>50?"...":"");
571
- trimContext();
572
- input.value="";input.style.height="auto";isProcessing=true;abortController=new AbortController();saveConversations();setProcessingUI(true);removeStreamingBubble();clearStepBars();
573
- var es=document.getElementById("emptyState");if(es)es.remove();var container=document.getElementById("messages");
574
- var uel=createMessageElement(chat.messages[chat.messages.length-1]);if(uel)container.appendChild(uel);
575
- renderChatHistory();if(autoScroll)scrollToBottom();var stepCount=0;
576
- try{while(stepCount<MAX_STEPS){stepCount++;addStepBar(stepCount,MAX_STEPS,"fa-brain","Thinking...");
577
- var sysP=getSystemPrompt(),modDesc=ModuleSystem.getToolDescriptions(),ctx=modDesc?"\n\n## Available Module Tools\n"+modDesc:"";/* wiki context injection */try{var wikiCtx=await ModuleSystem.getContext(text,{activeTool:null});if(wikiCtx)ctx+='\n\n'+wikiCtx;}catch(e){}
578
- var apiMsgs=[];if(sysP||ctx)apiMsgs.push({role:"system",content:(sysP||"You are HuggingBot.")+ctx});
579
- for(var i=0;i<chat.messages.length;i++)apiMsgs.push(chat.messages[i]);
580
- var response=await fetch("https://openrouter.ai/api/v1/chat/completions",{method:"POST",headers:{"Authorization":"Bearer "+API_KEY,"Content-Type":"application/json","HTTP-Referer":window.location.href,"X-Title":"HuggingBot"},body:JSON.stringify({model:selectedModelId||"openai/gpt-4o",messages:apiMsgs,tools:CORE_TOOLS.length>0?CORE_TOOLS:undefined,tool_choice:"auto",stream:true}),signal:abortController.signal});
581
- if(!response.ok)throw new Error("API "+response.status);
582
- var reader=response.body.getReader(),decoder=new TextDecoder(),buf="",fullContent="",toolCalls={},toolCallOrder=[],rt=null;
583
- startStreamingBubble();
584
- while(true){var rd=await reader.read();if(rd.done)break;buf+=decoder.decode(rd.value,{stream:true});var lines=buf.split("\n");buf=lines.pop()||"";for(var li=0;li<lines.length;li++){var line=lines[li];if(line.indexOof("data: ")!==0)continue;var json=line.slice(6).trim();if(!json||json==="[DONE]")continue;try{var chunk=JSON.parse(json);var d=(chunk.choices&&chunk.choices[0])?(chunk.choices[0].delta||{}):{};if(d.content){fullContent+=d.content;if(!rt)rt=setTimeout(function(){rt=null;updateStreamingContent(renderMarkdown(fullContent));},30);}if(d.tool_calls){for(var tci=0;tci<d.tool_calls.length;tci++){var tc=d.tool_calls[tci],idx=tc.index||0;if(!toolCalls[idx]){toolCalls[idx]={index:idx,id:tc.id||("tc_"+Date.now()+"_"+idx),type:"function",function:{name:"",arguments:""}};toolCallOrder.push(idx);}if(tc.function){if(tc.function.name)toolCalls[idx].function.name+=tc.function.name;if(tc.function.arguments)toolCalls[idx].function.arguments+=tc.function.arguments;}}}}catch(ex){}}}
585
- if(rt){clearTimeout(rt);rt=null;}if(fullContent&&streamBodyEl)updateStreamingContent(renderMarkdown(fullContent));removeStreamingBubble();
586
- var consolidatedCalls=[];for(var oi=0;oi<toolCallOrder.length;oi++){var idx=toolCallOrder[oi],tc=toolCalls[idx];if(tc)consolidatedCalls.push({id:tc.id,type:"function",function:{name:tc.function.name,arguments:tc.function.arguments}};}
587
- if(consolidatedCalls.length>0){if(window.LineEditor)window.LineEditor._batchBase=[];var tcMsg={role:"assistant",content:fullContent||null,tool_calls:consolidatedCalls,timestamp:getTimeStr()};chat.messages.push(tcMsg);chat.updatedAt=new Date().toISOString();var tcEl=createMessageEement(tcMsg);if(tcEl)container.appendChild(tcEl);
588
- for(var tci=0;tci<consolidatedCalls.length;tci++){var tc=consolidatedCalls[tci],args;try{args=JSON.parse(tc.function.arguments);}catch(ex){showToast("Failed to parse tool args");continue;}
589
- try{var moduleResult=await ModuleSystem.handleToolCall(tc.function.name,args,tc.id);if(moduleResult!==null){var toolContent=typeof moduleResult==="string"?moduleResult:JSON.stringify(moduleResult);chat.messages.push({role:"tool",tool_call_id:tc.id,content:toolContent,timestamp:getTimeStr()});var toolEl=createMessageElement({role:"tool",tool_call_id:tc.id,content:toolContent,timestamp:getTimeStr()});if(toolEl)container.appendChild(toolEl);}
590
- else if(tc.function.name==="evolve_self"){var lineResult=window.handleEvolveSelfLineAction(args);if(lineResult!==null){chat.messages.push({role:"tool",tool_call_id:tc.id,content:lineResult,timestamp:getTimeStr()});var toolEl=createMessageElement({role:"tool",tool_call_id:tc.id,content:lineResult,timestamp:getTimeStr()});if(toolEl)container.appendChild(toolEl);}
591
- else{var unk="Unknown action "+(args.action||"?")+"?";chat.messages.push({role:"tool",tool_call_id:tc.id,content:unk,timestamp:getTimeStr()});var toolEl=createMessageEement({role:"tool",tool_call_id:tc.id,content:unk,timestamp:getTimeStr()});if(toolEl)container.appendChild(toolEl);}}
592
- else{var na="Tool "+tc.function.name+" not available.";chat.messages.push({role:"tool",tool_call_id:tc.id,content:na,timestamp:getTimeStr()});var toolEl=createMessageEement({role:"tool",tool_call_id:tc.id,content:na,timestamp:getTimeStr()});if(toolEl)container.appendChild(toolEl);}}
593
- catch(terr){var errMsg="Error: "+terr.message;chat.messages.push({role:"tool",tool_call_id:tc.id,content:errMsg,timestamp:getTimeStr()});var toolEl=createMessageEement({role:"tool",tool_call_id:tc.id,content:errMsg,timestamp:getTimeStr()});if(toolEl)container.appendChild(toolEl);showToast("Tool error");}}
594
- removeStepBar();saveConversations();updateTokenDisplay();try{ModuleSystem.onResponse(text,fullContent||"",consolidatedCalls,{});}catch(e){}continue;}
595
- else if(fullContent){var finalMsg={role:"assistant",content:fullContent,timestamp:getTimeStr()};chat.messages.push(finalMsg);chat.updatedAt=new Date().toISOString();var el=createMessageEement(finalMsg);if(el)container.appendChild(el);removeStepBar();saveConversations();updateTokenDisplay();try{ModuleSystem.onResponse(text,fullContent,[],{});}catch(e){}break;}
596
- else{try{var sysP2=getSystemPrompt(),md2=ModuleSystem.getToolDescriptions(),ctx2=md2?"\n\nModule tools: "+md2:"";try{var wikiCtx2=await ModuleSystem.getContext(text,{activeTool:null});if(wikiCtx2)ctx2+="\n\n"+wikiCtx2;}catch(e){}var am2=[];if(sysP2||ctx2)am2.push({role:"system",content:(sysP2||"Yo are HuggingBot.")+ctx2});for(var i=0;i<chat.messages.length;i++)am2.push(chat.messages[i]);var fb=await fetch("https://openrouter.ai/api/v1/chat/completions",{method:"POST",headers:{"Authorization":"Bearer "+API_KEY,"Content-Type":"application/json"},body:JSON.stringify({model:selectedModelId||"openai/gpt-4o",messages:am2,tools:CORE_TOOLS.length>0?CORE_TOOLS:undefined,tool_choice:"auto",stream:false})});if(!fb.ok)throw Error("FB "+fb.status);var fd=await fb.json(),fm=fd.choiches&&fd.choiches[0]?fd.choiches[0].message:null;
597
- if(fm&&fm.tool_calls&&fm.tool_calls.length){if(window.LineEditor)window.LineEditor._batchBase=[];var ftm={role:"assistant",content:fm.content||null,tool_calls:fm.tool_calls,timestamp:getTimeStr()};chat.messages.push(ftm);var fte=createMessageEement(ftm);if(fte)container.appendChild(fte);
598
- for(var fi=0;fi<fm.tool_calls.length;fi++){var ft=fm.tool_calls[fi],fa;try{fa=JSON.parse(ft.function.arguments);}catch(ex){continue;}
599
- var mr=await ModuleSystem.handleToolCall(ft.function.name,fa,ft.id);
600
- if(mr!==null){var ct=typeof mr==="string"?mr:JSON.stringify(mr);chat.messages.push({role:"tool",tool_call_id:ft.id,content:ct,timestamp:getTimeStr()});var fel=createMessageEement({role:"tool",tool_call_id:ft.id,content:ct,timestamp:getTimeStr()});if(fel)container.appendChild(fel);}
601
- else if(ft.function.name==="evolve_self"){var lr2=window.handleEvolveSelfLineAction(fa);if(lr2!==null){chat.messages.push({role:"tool",tool_call_id:ft.id,content:lr2,timestamp:getTimeStr()});var fel=createMessageEement({role:"tool",tool_call_id:ft.id,content:lr2,timestamp:getTimeStr()});if(fel)container.appendChild(fel);}
602
- else{var d=(fa.action||"Done")+": "+(fa.description||"");chat.messages.push({role:"tool",tool_call_id:ft.id,content:d,timestamp:getTimeStr()});var fel=createMessageEement({role:"tool",tool_call_id:ft.id,content:d,timestamp:getTimeStr()});if(fel)container.appendChild(fel);}}
603
- else{var n="Tool "+ft.function.name+" not available.";chat.messages.push({role:"tool",tool_call_id:ft.id,content:n,timestamp:getTimeStr()});var fel=createMessageEement({role:"tool",tool_call_id:ft.id,content:n,timestamp:getTimeStr()});if(fel)container.appendChild(fel);}}
604
- removeStepBar();saveConversations();chat.updatedAt=new Date().toISOString();updateTokenDisplay();try{ModuleSystem.onResponse(text,fm.content||"",fm.tool_calls||[],{});}catch(e){}continue;}
605
- else{var ff={role:"assistant",content:(fm&&fm.content)||"",timestamp:getTimeStr()};chat.messages.push(ff);chat.updatedAt=new Date().toISOString();var fe=createMessageEement(ff);if(fe)container.appendChild(fe);removeStepBar();saveConversations();updateTokenDisplay();try{ModuleSystem.onResponse(text,fm.content||"",[],{});}catch(e){}break;}}
606
- catch(fbe){showToast("Fallback failed: "+fbe.message);removeStepBar();saveConversations();break;}}}
607
- removeStepBar();saveConversations();updateTokenDisplay();attachCopyButtons();
608
- if(stepCount>=MAX_STEPS)showToast("Max steps ("+MAX_STEPS+") reached");else if(stepCount>0)showToast("Complete");
609
- }catch(err){removeStepBar();removeStreamingBubble();if(err.name==="AbortError")showToast("Canceled");else{console.error(err);showToast("Error: "+err.message);}saveConversations();updateTokenDisplay();}
610
- finally{isProcessing=false;abortController=null;setProcessingUI(false);}}
611
-
612
- function cancelStream(){if(abortController){abortController.abort();abortController=null;}isProcessing=false;setProcessingUI(false);removeStreamingBubble();clearStepBars();}
613
-
614
  </script></body></html>
 
282
  renderChatHistory();
283
  var el=document.getElementById("storageModeSelect");
284
  if(el){el.value="localStorage";onStorageModeChange();}
285
+ if(conversations.length>0)loadChat(conversations[0].id)else newChat();
286
  });
287
  } else {
288
  renderChatHistory();
289
  var el=document.getElementById("storageModeSelect");
290
+ ifel){el.value=storageModeonStorageModeChange();}
291
  setTimeout(function(){
292
+ if!currentChatId){
293
+ if(conversations.length>0)loadChat(conversations[0.id);else newChat();}
294
+ },50);}
 
 
 
295
 
296
  // ===== SANITIZATION UTILITIES =====
297
+ function sanitizeHTML(str){if(typeof DOMPurify!=="undefined")return DOMPurify.sanitize(str{ALLOWED_TAGS:[],ALLOWED_ATTR:[]})var d=document.createEement("div");d.textContent=str;return d.inerHTML;}
298
+ function safeRenderHTML(html,allowSafeTags){try{if(typeof DOMPurify!=="undefined"){if(allowSafeTags)return DOMPurify.sanitize(html,{ALLOWED_TAGS:["div","span","a","b","i","em","strong","code","pre","br","p","h1","h2","h3","h4","h5","h6","ul","ol","li","blockquote","table","thead","tbody","tr","th","td","hr","img","figure","figcaption","dl","dt","dd","sup","sub","kbd","s","del","ins","mark","small","details","summary","button"],ALLOWED_ATTR:["href","target","rel","src","alt","class","id","title","width","height","style","data-*"],ALLOW_DATA_ATTR:true,FORBID_TAGS:["style","script","iframe","object","embed","form","input","textarea","select","option","optgroup","svg","math","link","meta","video","audio","canvas","applet","frame","frameset","noframes","noscript"],FORBID_ATTR:["onerror","onload","onclick","onmouseover","onmouseout","onkeydown","onkeyup","onchange","onsubmit","onfocus","onblur","onabort","onanimationstart","onanimationend","onauxclick","onbeforeinput","onbeforetoggle","oncancel","oncanplay","oncanplaythrough","onclose","oncontextmenu","oncopy","oncuechange","oncut","ondblclick","ondrag","ondragend","ondragenter","ondragleave","ondragover","ondragstart","ondrop","ondurationchange","onemptied","onended","onerror","onformdata","ongotpointercapture","oninput","oninvalid","onlostpointercapture","onpaste","onpase","onplay","onplaying","onpointercancel","onpointerenter","onpointerleave","onpointermove","onpointerout","onpointerover","onpointerrawupdate","onpointerup","onprogress","onratechange","onreset","onresize","onscroll","onsecuritypolicyviolation","onseeked","onseeking","onselect","onselectionchange","onselectstart","onslotchange","onstalled","onsubmit","onsuspend","ontimeupdate","ontoggle","ontransitioncancel","ontransitionend","ontransitionrun","ontransitionstart","onvolumechange","onwaiting","onwebkitanimationend","onwebkitanimationiteration","onwebkitanimationstart","onwebkittransitionend","onwheel","style"],ADD_ATTR:["target"],WHOLE_DOCUMENT:false});}return DOMPurify.sanitize(html);var d=document.createElement("div");d.textContent=html.replace(/<[^>]*>/g,"");return d.innerHTML;}catch(ex){var d=document.createElement("div");d.textContent=html;return d.innerHTML;}}
299
  function safeSetInnerHTML(el,html){try{el.innerHTML=html;}catch(ex){el.textContent=html;}}
300
+ function renderMarkdown(text){if(!text)return "";try{var raw=marked.parse(text,{breaks:true,gfm:true});return safeRenderHTML(raw,true);}catch(ex){var d=document.createElement("div");d.textContent=text;return d.innerHTML;}}
301
  function showToast(msg){var t=document.getElementById("toast");t.textContent=msg;t.classList.remove("hidden");clearTimeout(t._timeout);t._timeout=setTimeout(function(){t.classList.add("hidden");},3500);}
302
  function scrollToBottom(smooth){if(smooth===undefined)smooth=true;var c=document.getElementById("messages");c.scrollTop=c.scrollHeight;}
303
  function getTimeStr(){var d=new Date();return d.toLocaleTimeString([],{hour:"2-digit",minute:"2-digit"});}
304
  function updateAutoScroll(){autoScroll=document.getElementById("autoScrollToggle").checked;}
305
+ function getCurrentChat(){for(var i=0;i<conversations.length;i++)if(conversations[i].id===currentChatId)return conersations[i];return null;}
306
+ function getStoragUsage(){var result={used:0,limit:5242880,pct:0};try{var total=0;for(var key in localStorag){if(localStorage.hasOwnProperty(key)}total+=localStorag[key].length;}result.used=total;result.pct=Math.min(100,Math.round((total/result.limit)*100));}catch(ex){}return result;}
307
+ function formtBytes(bytes){if(bytes<1024)return bytes+" B";if(bytes<1048576)return(bytes/1024).toFixed(1)+" KB";return(bytes/1048576).toFixed(1)+" MB";}
308
+ function showConfirmDialog(msg,callback){confirmCallback=callaack;var modal=document.getElementById("confirmModal");document.getElementById("confirmModalBody").textContent=msg;modal.classList.add("show");}
 
309
  document.getElementById("confirmOkBtn").addEventListener("click",function(){var cb=confirmCallback;confirmCallback=null;document.getElementById("confirmModal").classList.remove("show");if(cb)cb(true);});
310
  document.getElementById("confirmCancelBtn").addEventListener("click",function(){var cb=confirmCallback;confirmCallback=null;document.getElementById("confirmModal").classList.remove("show");if(cb)cb(false);});
311
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
312
  </script></body></html>