diff --git a/scripts/docs-site/assets.mjs b/scripts/docs-site/assets.mjs index 6ec230780..9048a81dd 100644 --- a/scripts/docs-site/assets.mjs +++ b/scripts/docs-site/assets.mjs @@ -43,7 +43,7 @@ function addChatThinking(){const log=document.querySelector("[data-chat-log]");i function setChatClearVisible(visible){const btn=document.querySelector("[data-chat-clear]");if(!btn)return;if(visible)btn.removeAttribute("hidden");else btn.setAttribute("hidden","")} function clearChat(){const log=document.querySelector("[data-chat-log]");if(!log)return;log.innerHTML='

Ask about install, channels, gateway config, or plugin APIs.

';log.scrollTop=0;setChatClearVisible(false);document.querySelector("[data-chat-input]")?.focus()} function isAuthFetchError(err){const msg=String(err?.message||err||"").toLowerCase();return msg==="auth_required"||msg.includes("load failed")||msg.includes("failed to fetch")||msg.includes("networkerror")} -function chatSignInUrl(){const url=new URL("/ask-molty/sign-in",location.origin);url.searchParams.set("return_to",location.href);return url.href} +function chatSignInUrl(){const url=new URL("https://hub.openclaw.ai/docs/auth");url.searchParams.set("return_to",location.href);return url.href} function initChat(){const chat=document.querySelector("[data-docs-chat]");const auth=document.querySelector("[data-chat-auth]");const form=document.querySelector("[data-chat-form]");const input=document.querySelector("[data-chat-input]");const submit=document.querySelector("[data-chat-submit]");if(!chat||!form||!input)return;let authState="unknown";let authPromise=null;const setAuthState=state=>{authState=state;if(auth){auth.hidden=state!=="checking"&&state!=="required";if(state==="checking")auth.innerHTML='
Checking GitHub verification...

One moment.

';if(state==="required")auth.innerHTML='
Verify with GitHub

Any GitHub account can use Ask Molty. Verify once, then ask your docs question.

Verify with GitHub
'}form.hidden=state!=="ready";input.disabled=state!=="ready";if(submit)submit.disabled=state!=="ready"};const ensureAuth=async()=>{if(authState==="ready")return true;if(authPromise)return authPromise;setAuthState("checking");authPromise=(async()=>{const api=window.OPENCLAW_DOCS_CHAT_API;if(!api)throw new Error("AUTH_REQUIRED");try{const res=await fetch(api,{method:"GET",credentials:"same-origin",redirect:"manual",headers:{"Accept":"application/json"}});if(res.type==="opaqueredirect"||res.redirected||res.status===0||res.status===401||res.status===403)throw new Error("AUTH_REQUIRED");if(!res.ok)throw new Error("AUTH_REQUIRED");setAuthState("ready");setTimeout(()=>input.focus(),0);return true}catch(err){setAuthState("required");return false}finally{authPromise=null}})();return authPromise};const setOpen=open=>{chat.classList.toggle("open",open);document.querySelector("[data-chat-toggle]")?.setAttribute("aria-expanded",String(open));if(open)ensureAuth().then(ok=>{if(ok)setTimeout(()=>input.focus(),0)})};setAuthState("unknown");document.addEventListener("click",e=>{if(e.target.closest("[data-chat-toggle]")){setOpen(!chat.classList.contains("open"));return}if(e.target.closest("[data-chat-close]")){setOpen(false);return}if(e.target.closest("[data-chat-clear]")){clearChat();return}});input.addEventListener("keydown",e=>{if(e.key==="Enter"&&!e.shiftKey){e.preventDefault();form.requestSubmit()}});form.addEventListener("submit",async e=>{e.preventDefault();const api=window.OPENCLAW_DOCS_CHAT_API;const message=input.value.trim();if(!api||!message)return;if(!await ensureAuth())return;input.value="";addChatMessage("user",message);setChatClearVisible(true);const reply=addChatThinking();submit.disabled=true;try{const res=await fetch(api,{method:"POST",headers:{"Content-Type":"application/json"},credentials:"same-origin",redirect:"manual",body:JSON.stringify({message,retrieval:"auto",confidenceThreshold:.3})});if(res.type==="opaqueredirect"||res.redirected||res.status===0||res.status===401||res.status===403)throw new Error("AUTH_REQUIRED");if(!res.ok)throw new Error("Docs agent returned "+res.status);if(!res.body)throw new Error("Docs agent did not stream a response");const reader=res.body.getReader();const decoder=new TextDecoder();let raw="";while(true){const {done,value}=await reader.read();if(done)break;raw+=decoder.decode(value,{stream:true});if(reply&&raw.trim()){if(reply.classList.contains("thinking"))reply.classList.remove("thinking");reply.innerHTML="

"+renderChatText(raw)+"

";reply.parentElement.scrollTop=reply.parentElement.scrollHeight}}if(!raw&&reply){reply.classList.remove("thinking");reply.innerHTML="

No response.

"}}catch(err){if(reply){const msg=isAuthFetchError(err)?"[Verify with GitHub]("+chatSignInUrl()+"), then ask again.":err?.message||"Docs agent failed.";reply.className="docs-chat-message error";reply.innerHTML="

"+renderChatText(msg)+"

";if(isAuthFetchError(err))setAuthState("required")}}finally{submit.disabled=authState!=="ready";if(authState==="ready")input.focus()}})} initChat(); document.addEventListener("click",async e=>{const theme=e.target.closest("[data-theme-toggle]");if(theme){const next=root.dataset.theme==="dark"?"light":"dark";root.dataset.theme=next;localStorage.setItem("theme",next);return}const trigger=e.target.closest("[data-language-trigger]");if(trigger){e.stopPropagation();toggleLanguage();return}const picker=document.querySelector("[data-language-picker]");if(picker&&!picker.contains(e.target))closeLanguage();const navToggle=e.target.closest("[data-nav-toggle]");if(navToggle){document.querySelector(".sidebar")?.classList.toggle("open");return}if(e.target.closest("[data-search-open]")){openSearch();return}if(e.target.closest("[data-search-close]")){modal?.classList.remove("open");return}const link=e.target.closest("a[href]");if(!link)return;if(link.closest("[data-language-picker]"))return;if(link.target||link.download||!isPlainLeftClick(e))return;const url=new URL(link.href,location.href);if(url.pathname===location.pathname&&url.search===location.search&&url.hash)return;if(!isDocsPage(url))return;e.preventDefault();modal?.classList.remove("open");const ok=await navigateTo(url);if(!ok)location.href=url.href});