dewee-webchat 0.4.2 → 0.5.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -21,7 +21,7 @@ function isLinkErrorCode(code) {
21
21
  }
22
22
  var HEADER_GATEWAY_URL = "x-dewee-gateway-url";
23
23
  var HEADER_GATEWAY_TOKEN = "x-dewee-gateway-token";
24
- var VERSION = "0.4.2";
24
+ var VERSION = "0.5.0-beta.1";
25
25
 
26
26
  // src/actions/page-block.ts
27
27
  var ACTION_NAME_RE = /^[a-z][a-z0-9_.-]{0,63}$/;
@@ -1,27 +1,27 @@
1
- "use strict";(()=>{var ue=Object.defineProperty;var ze=(t,s,e)=>s in t?ue(t,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[s]=e;var qe=(t,s)=>{for(var e in s)ue(t,e,{get:s[e],enumerable:!0})};var g=(t,s,e)=>ze(t,typeof s!="symbol"?s+"":s,e);var de={};qe(de,{ApiClient:()=>R,ApiError:()=>E,DOM_ACTION_NAMES:()=>Te,DeweeChatElement:()=>H,RESERVED_HEADERS:()=>ae,defineDeweeChat:()=>le,mount:()=>Tt,renderMarkdown:()=>M});var Je=["IDENTITY_REQUIRED","IDENTITY_LINK_REQUIRED","IDENTITY_CONFLICT","LINK_EXPIRED","LINK_REVOKED","PERMISSION_DENIED","SOURCE_UNAVAILABLE"];function z(t){return typeof t=="string"&&Je.includes(t)}var Ve=["POLICY_DENIED","RATE_LIMITED","CHALLENGE_REQUIRED"];function q(t){return typeof t=="string"&&Ve.includes(t)}var Ue=["idempotency_key_reused","link_in_progress","linking_unavailable"];function pe(t){return typeof t=="string"&&Ue.includes(t)}var J="x-dewee-gateway-url",V="x-dewee-gateway-token";var he="dewee-action",ge="dewee-action-result",D={maxCalls:8,maxBlockBytes:8192},Ke=/^[A-Za-z0-9_.:-]{1,64}$/,Ye=/^\s{0,3}```\s*$/,fe=t=>new RegExp("^\\s{0,3}```"+t.replace(/[.-]/g,"\\$&")+"\\s*$"),me=fe(he),be=fe(ge);function U(t,s){let e=[];for(let n=0;n<t.length;n++){if(!s.test(t[n]))continue;let i=n,o=[],r=!1;for(n++;n<t.length;n++){if(Ye.test(t[n])){r=!0;break}o.push(t[n])}e.push({start:i,end:Math.min(n,t.length-1),body:o,closed:r})}return e}var we=(t,s)=>{let e=new Set;for(let n of s)for(let i=n.start;i<=n.end;i++)e.add(i);return t.filter((n,i)=>!e.has(i)).join(`
1
+ "use strict";(()=>{var be=Object.defineProperty;var Qe=(t,s,e)=>s in t?be(t,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[s]=e;var Xe=(t,s)=>()=>(t&&(s=t(t=0)),s);var we=(t,s)=>{for(var e in s)be(t,e,{get:s[e],enumerable:!0})};var f=(t,s,e)=>Qe(t,typeof s!="symbol"?s+"":s,e);var Ve={};we(Ve,{capturePageContext:()=>Mt,providedPageContext:()=>Pt,safePageUrl:()=>Ue});function Ue(t){try{let s=new URL(t);if(s.protocol!=="https:"&&s.protocol!=="http:")return;s.username="",s.password="",s.hash="";for(let e of[...s.searchParams.keys()]){let n=e.replace(/(\p{Lu}+)(\p{Lu}\p{Ll})/gu,"$1 $2").replace(/([\p{Ll}\p{N}])(\p{Lu})/gu,"$1 $2").replace(/(\p{L})(\p{N})/gu,"$1 $2").replace(/(\p{N})(\p{L})/gu,"$1 $2").toLowerCase().split(/[^\p{L}\p{N}]+/u).filter(Boolean),i=n.join(""),r=["api","access","auth","oauth","secret","private","client","session","signing","verification","reset","recovery","activation","confirmation","invite","license","encryption"];(n.some((c,a)=>["token","secret","password","passwd","pwd","auth","authorization","cookie","apikey","session","sid","sig","signature","otp","jwt","credential","credentials","nonce","bearer","ticket"].includes(c)||["code","key","state"].includes(c)&&(n.length===1||a>0&&r.includes(n[a-1])))||/token|secret|passw|apikey|credential|sessid|session|authorization|samlresponse/.test(i))&&s.searchParams.set(e,"[REDACTED]")}return new TextEncoder().encode(s.href).length<=2048?s.href:void 0}catch{return}}function I(t,s){return Array.from(t).slice(0,s).join("")}function Je(t){if(t.content&&new TextEncoder().encode(JSON.stringify(t)).length>65536){let s=Array.from(t.content.text),e=0,n=s.length;for(;e<n;){let i=Math.ceil((e+n)/2);t.content.text=s.slice(0,i).join(""),t.content.truncated=!0,new TextEncoder().encode(JSON.stringify(t)).length<=65536?e=i:n=i-1}t.content.text=s.slice(0,e).join(""),t.content.truncated=!0}return t}function Pt(t,s,e){if(!t||typeof t!="object"||Array.isArray(t))throw new TypeError("Invalid page context");let n=t,i={version:1,url:s.url,captured_at:s.captured_at};for(let[r,o]of[["title",300],["description",1e3]])typeof n[r]=="string"&&(i[r]=I(n[r].replace(/\s+/g," ").trim(),o));if(e==="content"&&(typeof n.selection=="string"&&(i.selection=I(n.selection,2e3)),n.content&&typeof n.content=="object"&&!Array.isArray(n.content))){let r=n.content;if(typeof r.text!="string"||r.format!=="text"&&r.format!=="markdown")throw new TypeError("Invalid page content");let o=I(r.text,12e3);i.content={format:r.format,text:o,truncated:r.truncated===!0||Array.from(r.text).length>12e3}}return Je(i)}function V(t,s){for(let e=t;e;e=e.parentElement){if(e.matches(Lt)||s.some(i=>e.matches(i))||e instanceof HTMLDialogElement&&!e.open)return!1;if(e instanceof HTMLDetailsElement&&!e.open){let i=[...e.children].find(r=>r.tagName==="SUMMARY");if(!i||!t||i!==t&&!i.contains(t))return!1}if(e.hasAttribute("popover"))try{if(!e.matches(":popover-open"))return!1}catch{return!1}let n=getComputedStyle(e);if(n.display==="none"||n.visibility==="hidden"||n.visibility==="collapse"||n.opacity==="0"||n.contentVisibility==="hidden")return!1}return!(t&&typeof t.checkVisibility=="function"&&!t.checkVisibility({checkOpacity:!0,checkVisibilityCSS:!0}))}function Mt(t,s){let e=Ue(t.location.href);if(!e)return;let n=s.excludeSelectors??[];for(let m of n)t.documentElement.matches(m);let i=t.querySelector(s.selector||"main, article, [role='main']"),r={version:1,url:e,captured_at:new Date().toISOString()},o=I(t.title.replace(/\s+/g," ").trim(),300),c=I((t.querySelector('meta[name="description" i]')?.getAttribute("content")??"").replace(/\s+/g," ").trim(),1e3);if(o&&(r.title=o),c&&(r.description=c),s.mode!=="content"||!i||!V(i,n))return r;let a=t.createTreeWalker(i,NodeFilter.SHOW_TEXT),d=[],l=0,p=0,g=!1;for(;a.nextNode();){if(++p>5e3){g=!0;break}let m=a.currentNode;if(!V(m.parentElement,n))continue;let b=(m.textContent??"").replace(/\s+/g," ").trim();if(!b)continue;let x=12e3-l,w=I(b,x);if(d.push(w),l+=Array.from(w).length+1,Array.from(b).length>x||l>=12e3){g=!0;break}}let h=I(d.join(`
2
+ `),12e3);h&&(r.content={format:"text",text:h,truncated:g});let u=t.getSelection();if(u&&!u.isCollapsed&&u.rangeCount){let m=u.getRangeAt(0),b=m.commonAncestorContainer,x=b.nodeType===Node.ELEMENT_NODE?b:b.parentElement;if(x&&i.contains(x)&&V(x,n)){let w=i.querySelectorAll("*");if(w.length<=5e3&&![...w].some(y=>m.intersectsNode(y)&&!V(y,n))){let y=I(u.toString().trim(),2e3);y&&(r.selection=y)}}}return Je(r)}var Lt,Ke=Xe(()=>{"use strict";Lt="script,style,noscript,template,svg,canvas,iframe,form,input,textarea,select,option,button,[contenteditable]:not([contenteditable='false']),[hidden],[aria-hidden='true'],[inert],dewee-chat"});var me={};we(me,{ApiClient:()=>M,ApiError:()=>E,DOM_ACTION_NAMES:()=>_e,DeweeChatElement:()=>D,RESERVED_HEADERS:()=>he,defineDeweeChat:()=>fe,mount:()=>qt,renderMarkdown:()=>R});var Ze=["IDENTITY_REQUIRED","IDENTITY_LINK_REQUIRED","IDENTITY_CONFLICT","LINK_EXPIRED","LINK_REVOKED","PERMISSION_DENIED","SOURCE_UNAVAILABLE"];function Y(t){return typeof t=="string"&&Ze.includes(t)}var et=["POLICY_DENIED","RATE_LIMITED","CHALLENGE_REQUIRED"];function G(t){return typeof t=="string"&&et.includes(t)}var tt=["idempotency_key_reused","link_in_progress","linking_unavailable"];function ye(t){return typeof t=="string"&&tt.includes(t)}var W="x-dewee-gateway-url",F="x-dewee-gateway-token";var xe="dewee-action",ve="dewee-action-result",$={maxCalls:8,maxBlockBytes:8192},nt=/^[A-Za-z0-9_.:-]{1,64}$/,it=/^\s{0,3}```\s*$/,Ee=t=>new RegExp("^\\s{0,3}```"+t.replace(/[.-]/g,"\\$&")+"\\s*$"),ke=Ee(xe),st=Ee(ve);function Q(t,s){let e=[];for(let n=0;n<t.length;n++){if(!s.test(t[n]))continue;let i=n,r=[],o=!1;for(n++;n<t.length;n++){if(it.test(t[n])){o=!0;break}r.push(t[n])}e.push({start:i,end:Math.min(n,t.length-1),body:r,closed:o})}return e}var Ae=(t,s)=>{let e=new Set;for(let n of s)for(let i=n.start;i<=n.end;i++)e.add(i);return t.filter((n,i)=>!e.has(i)).join(`
2
3
  `).replace(/\n{3,}/g,`
3
4
 
4
- `).trim()};function K(t){let s=t.replace(/\r\n?/g,`
5
+ `).trim()};function X(t){let s=t.replace(/\r\n?/g,`
5
6
  `).split(`
6
- `),e=U(s,me),n=[],i=new Set;return e.forEach((o,r)=>{let a=`call-${r+1}`,d=o.body.join(`
7
- `),l=(h,m=a,b="")=>n.push({ok:!1,id:m,name:b,error:h});if(r>=D.maxCalls)return l(`Too many action calls in one reply (max ${D.maxCalls})`);if(!o.closed)return l("Unclosed dewee-action block");if(new TextEncoder().encode(d).length>D.maxBlockBytes)return l(`Action block exceeds ${D.maxBlockBytes} bytes`);let c;try{c=JSON.parse(d)}catch{return l("Action block is not valid JSON")}if(typeof c!="object"||c===null||Array.isArray(c))return l("Action block must be a JSON object");let u=typeof c.id=="string"&&Ke.test(c.id)?c.id:a,f=typeof c.name=="string"?c.name.slice(0,64):"";if(i.has(u))return l(`Duplicate action call id "${u}"`,`${u}-${r+1}`,f);if(i.add(u),!f)return l("Action name is required",u);let p=c.args??{};if(typeof p!="object"||p===null||Array.isArray(p))return l("args must be a JSON object",u,f);n.push({ok:!0,id:u,name:f,args:p})}),{text:e.length?we(s,e):t,calls:n}}function ye(t){if(!t.includes("```"+he))return t;let s=t.replace(/\r\n?/g,`
7
+ `),e=Q(s,ke),n=[],i=new Set;return e.forEach((r,o)=>{let c=`call-${o+1}`,a=r.body.join(`
8
+ `),d=(u,m=c,b="")=>n.push({ok:!1,id:m,name:b,error:u});if(o>=$.maxCalls)return d(`Too many action calls in one reply (max ${$.maxCalls})`);if(!r.closed)return d("Unclosed dewee-action block");if(new TextEncoder().encode(a).length>$.maxBlockBytes)return d(`Action block exceeds ${$.maxBlockBytes} bytes`);let l;try{l=JSON.parse(a)}catch{return d("Action block is not valid JSON")}if(typeof l!="object"||l===null||Array.isArray(l))return d("Action block must be a JSON object");let p=typeof l.id=="string"&&nt.test(l.id)?l.id:c,g=typeof l.name=="string"?l.name.slice(0,64):"";if(i.has(p))return d(`Duplicate action call id "${p}"`,`${p}-${o+1}`,g);if(i.add(p),!g)return d("Action name is required",p);let h=l.args??{};if(typeof h!="object"||h===null||Array.isArray(h))return d("args must be a JSON object",p,g);n.push({ok:!0,id:p,name:g,args:h})}),{text:e.length?Ae(s,e):t,calls:n}}function Ce(t){if(!t.includes("```"+xe))return t;let s=t.replace(/\r\n?/g,`
8
9
  `).split(`
9
- `);return we(s,U(s,me))}function Y(t){return be.test(t.trimStart().split(`
10
- `,1)[0]??"")}function xe(t){let s=t.replace(/\r\n?/g,`
10
+ `);return Ae(s,Q(s,ke))}function Z(t){return/^\s*```dewee-action-result(?:\s|$)/.test(t)}function rt(t){let s=/```dewee-action-result\s+/g,e=[],n;for(;n=s.exec(t);){let i=s.lastIndex;if(t[i]!=="{")continue;let r=0,o=!1,c=!1;for(let a=i;a<t.length;a++){let d=t[a];if(o)c?c=!1:d==="\\"?c=!0:d==='"'&&(o=!1);else if(d==='"')o=!0;else if(d==="{")r++;else if(d==="}"&&--r===0){let l=/^\s*```/.exec(t.slice(a+1));l&&(e.push(t.slice(i,a+1)),s.lastIndex=a+1+l[0].length);break}}}return e}function Se(t){let s=t.replace(/\r\n?/g,`
11
11
  `).split(`
12
- `),e=[];for(let n of U(s,be))try{let i=JSON.parse(n.body.join(`
13
- `));i&&typeof i.id=="string"&&["ok","denied","error"].includes(i.status)&&e.push(i)}catch{}return e}var P=t=>"```"+ge+`
14
- `+JSON.stringify(t)+"\n```";function ve(t,s=4e3){let e=Math.max(64,Math.floor((s-16)/Math.max(1,t.length)));return t.map(i=>{let o={...i,result:F(i.result)};if(o.result===void 0&&delete o.result,P(o).length<=e)return P(o);let r=JSON.stringify(o.result??null),a=e-P({...o,result:{truncated:!0,preview:""}}).length-8,d=P({...o,result:{truncated:!0,preview:r.slice(0,Math.max(0,a))}});return d.length<=e?d:P({id:i.id,name:i.name.slice(0,64),status:i.status,result:{truncated:!0}})}).join(`
12
+ `),e=[],n=Q(s,st),i=n.length?n.map(r=>r.body.join(`
13
+ `)):rt(t);for(let r of i)try{let o=JSON.parse(r);o&&typeof o.id=="string"&&["ok","denied","error"].includes(o.status)&&e.push(o)}catch{}return e}var N=t=>"```"+ve+`
14
+ `+JSON.stringify(t)+"\n```";function Te(t,s=4e3){let e=Math.max(64,Math.floor((s-16)/Math.max(1,t.length)));return t.map(i=>{let r={...i,result:ee(i.result)};if(r.result===void 0&&delete r.result,N(r).length<=e)return N(r);let o=JSON.stringify(r.result??null),c=e-N({...r,result:{truncated:!0,preview:""}}).length-8,a=N({...r,result:{truncated:!0,preview:o.slice(0,Math.max(0,c))}});return a.length<=e?a:N({id:i.id,name:i.name.slice(0,64),status:i.status,result:{truncated:!0}})}).join(`
15
15
 
16
- `).slice(0,s)}function F(t){if(t!==void 0)try{let s=JSON.stringify(t);return s===void 0?null:JSON.parse(s)}catch{return"[unserializable result]"}}var W=t=>t===null?"null":Array.isArray(t)?"array":typeof t=="number"?Number.isInteger(t)?"integer":"number":typeof t,Fe=(t,s)=>{let e=W(t);return e===s||s==="number"&&e==="integer"};function O(t,s,e="args",n=0){if(!s||typeof s!="object")return null;if(n>32)return`${e}: schema is nested too deeply`;let i=s;if(i.type!==void 0){let o=Array.isArray(i.type)?i.type:[i.type];if(!o.some(r=>Fe(t,r)))return`${e}: expected ${o.join(" or ")}, got ${W(t)}`}if(Array.isArray(i.enum)&&!i.enum.some(o=>Ee(o,t)))return`${e}: must be one of ${i.enum.map(o=>JSON.stringify(o)).join(", ")}`;if("const"in i&&!Ee(i.const,t))return`${e}: must equal ${JSON.stringify(i.const)}`;if(typeof t=="string"){if(typeof i.minLength=="number"&&t.length<i.minLength)return`${e}: shorter than ${i.minLength} characters`;if(typeof i.maxLength=="number"&&t.length>i.maxLength)return`${e}: longer than ${i.maxLength} characters`;if(typeof i.pattern=="string"){let o=null;try{o=new RegExp(i.pattern,"u")}catch{return`${e}: schema pattern is invalid`}if(!o.test(t))return`${e}: does not match ${i.pattern}`}}if(typeof t=="number"){if(typeof i.minimum=="number"&&t<i.minimum)return`${e}: must be >= ${i.minimum}`;if(typeof i.maximum=="number"&&t>i.maximum)return`${e}: must be <= ${i.maximum}`}if(Array.isArray(t)){if(typeof i.minItems=="number"&&t.length<i.minItems)return`${e}: needs at least ${i.minItems} items`;if(typeof i.maxItems=="number"&&t.length>i.maxItems)return`${e}: allows at most ${i.maxItems} items`;if(i.items&&typeof i.items=="object")for(let o=0;o<t.length;o++){let r=O(t[o],i.items,`${e}[${o}]`,n+1);if(r)return r}}if(W(t)==="object"){let o=t,r=i.properties&&typeof i.properties=="object"?i.properties:{};for(let a of Array.isArray(i.required)?i.required:[])if(!(a in o))return`${e}.${a}: is required`;for(let[a,d]of Object.entries(o))if(Object.prototype.hasOwnProperty.call(r,a)){let l=O(d,r[a],`${e}.${a}`,n+1);if(l)return l}else if(i.additionalProperties===!1)return`${e}.${a}: is not allowed`}return null}function Ee(t,s){return JSON.stringify(t)===JSON.stringify(s)}var Ae=/^[a-z][a-z0-9_.-]{0,63}$/,G=["read","navigate","mutate","destructive"],S={maxActions:32,maxDescription:1e3,maxParametersBytes:4096,maxManifestBytes:16384,maxPageContextBytes:4096},We="[[dewee-page v1]]",ke="[[/dewee-page]]";function Q(t){if(!t.startsWith(We))return t;let s=t.indexOf(`
17
- `+ke);return s<0?t:t.slice(s+ke.length+1).replace(/^\n+/,"")}var Ge=t=>t==="mutate"||t==="destructive",N=class{constructor(){g(this,"map",new Map)}get size(){return this.map.size}get(s){return this.map.get(s)}names(){return[...this.map.keys()]}register(s){let e=Array.isArray(s)?s:[s];for(let n of e)Qe(n);if(new Set([...this.map.keys(),...e.map(n=>n.name)]).size>S.maxActions)throw new TypeError(`dewee-webchat: at most ${S.maxActions} page actions`);for(let n of e)this.map.set(n.name,n)}unregister(s){return this.map.delete(s)}manifest(){return[...this.map.values()].map(s=>({name:s.name,description:s.description,sensitivity:s.sensitivity,parameters:s.parameters??{type:"object",properties:{}}}))}};function Qe(t){let s=e=>{throw new TypeError(`dewee-webchat: invalid page action ${JSON.stringify(t?.name)}: ${e}`)};(!t||typeof t!="object")&&s("not an object"),(typeof t.name!="string"||!Ae.test(t.name))&&s("name must match ^[a-z][a-z0-9_.-]{0,63}$"),(typeof t.description!="string"||t.description.length>S.maxDescription)&&s(`description must be a string up to ${S.maxDescription} chars`),G.includes(t.sensitivity)||s(`sensitivity must be one of ${G.join(", ")}`),typeof t.handler!="function"&&s("handler must be a function"),t.parameters!==void 0&&(typeof t.parameters!="object"||t.parameters===null||Array.isArray(t.parameters))&&s("parameters must be a JSON Schema object")}async function Se(t,s){let e=d=>(s.onStatus?.("error"),{id:t.id,name:t.name,status:"error",error:d});if(!t.ok)return e(t.error);if(s.signal.aborted)return e("Cancelled");let n=s.registry.get(t.name);if(!n)return e(`Unknown action "${t.name}". Available: ${s.registry.names().join(", ")||"none"}`);let i=O(t.args,n.parameters??{type:"object"});if(i)return e(`Invalid arguments: ${i}`);if(Ge(n.sensitivity)){s.onStatus?.("awaiting-confirmation");let{handler:d,...l}=n,c=!1;try{c=await Ce(Promise.resolve(s.confirm({...l,callId:t.id},t.args)),s.signal)===!0}catch{c=!1}if(!c||s.signal.aborted)return s.onStatus?.("denied"),{id:t.id,name:t.name,status:"denied",error:"The user declined this action."}}s.onStatus?.("running");let o=new AbortController,r=()=>o.abort();s.signal.addEventListener("abort",r,{once:!0});let a=setTimeout(r,s.timeoutMs??3e4);try{let d=await Ce(Promise.resolve().then(()=>n.handler(t.args,{callId:t.id,conversationId:s.conversationId,agent:s.agent,signal:o.signal})),o.signal);return s.onStatus?.("done"),{id:t.id,name:t.name,status:"ok",result:F(d)??null}}catch(d){return e(o.signal.aborted?s.signal.aborted?"Cancelled":"Timed out":String(d?.message??d).slice(0,500)||"Action failed")}finally{clearTimeout(a),s.signal.removeEventListener("abort",r)}}function Ce(t,s){return s.aborted?Promise.reject(new Error("aborted")):new Promise((e,n)=>{let i=()=>n(new Error("aborted"));s.addEventListener("abort",i,{once:!0}),t.then(e,n).finally(()=>s.removeEventListener("abort",i))})}var Te=["page.snapshot","page.scroll","page.click","page.fill"],Ze=["a[href]","button","input","select","textarea","summary","[contenteditable]:not([contenteditable=false])",...["button","link","checkbox","radio","switch","tab","menuitem","option","combobox","textbox","searchbox"].map(t=>`[role=${t}]`)].join(","),Xe=new Set(["checkbox","radio","file","submit","button","image","reset","hidden","password"]),et=/\b(cc-[a-z-]+|one-time-code|current-password|new-password)\b/i,tt=/(passw|passcode|\bpin\b|otp|one.?time|cvv|cvc|card.?(num|no)|cc.?num|security.?code|\bssn\b)/i,ie=80,oe=60,nt=40,L=(t,s)=>t.length>s?t.slice(0,s-1)+"\u2026":t,k=t=>(t??"").replace(/\s+/g," ").trim(),Z={type:"string",pattern:"^e[0-9]{1,4}$"},X={type:"integer",minimum:1};function Ie(t){let s=0,e=new Map,n=()=>{let c=t.root(),u=typeof c=="string"?document.querySelector(c):c;if(c!==void 0&&!u)throw new Error(`domActionsRoot ${JSON.stringify(c)} matches no element`);return u??document.body},i=(c,u)=>c.isConnected&&u.contains(c)&&!t.exclude?.(c)&&!c.closest("[data-dewee-ignore]")&&!st(c)&&ot(c),o=c=>{if(c.generation!==s)throw new Error(`Stale ref: generation ${c.generation} is not the latest snapshot (${s||"none"}). Call page.snapshot again.`);let u=e.get(c.ref);if(!u)throw new Error(`Unknown ref "${c.ref}". Call page.snapshot again.`);if(!i(u,n()))throw new Error(`Ref "${c.ref}" is no longer available. Call page.snapshot again.`);return u};return{actions:[{name:"page.snapshot",description:'List the interactive elements visible on the page (links, buttons, form fields) as lines `ref role "name" [state]`. Use the ref together with the returned generation in page.scroll, page.click and page.fill. Every snapshot invalidates older refs. Use query to filter by visible name, offset/limit to page through long lists.',sensitivity:"read",parameters:{type:"object",properties:{query:{type:"string",maxLength:100},offset:{type:"integer",minimum:0},limit:{type:"integer",minimum:1,maximum:100}},additionalProperties:!1},handler:({query:c,offset:u=0,limit:f=nt})=>{let p=n();s++,e=new Map;let h=k(c).toLowerCase(),m=[],b=0;for(let v of p.querySelectorAll(Ze)){if(!i(v,p))continue;let w=te(v);if(h&&!w.toLowerCase().includes(h)||(b++,b<=u||m.length>=f))continue;let x=`e${b}`;e.set(x,v),m.push(`${x} ${w}`)}return{generation:s,url:location.pathname+location.search,title:L(document.title,ie),total:b,offset:u,elements:m,...ne(p)}}},{name:"page.scroll",description:"Scroll the page by about one screen (direction up/down) or to the top/bottom, or scroll an element from page.snapshot into view (ref + generation).",sensitivity:"read",parameters:{type:"object",properties:{direction:{type:"string",enum:["up","down","top","bottom"]},ref:Z,generation:X},additionalProperties:!1},handler:({direction:c,ref:u,generation:f})=>{let p=n();if(u!==void 0){if(f===void 0)throw new Error("generation is required with ref");return o({ref:u,generation:f}).scrollIntoView?.({block:"center",inline:"nearest"}),{ref:u,...ne(p)}}if(!c)throw new Error("Give a direction or a ref");let h=Re(p),m=h===null?window.innerHeight:h.clientHeight,b=h===null?window.scrollY:h.scrollTop,v=h===null?document.documentElement.scrollHeight:h.scrollHeight,w=c==="top"?0:c==="bottom"?v:b+(c==="down"?.8:-.8)*m;return h===null?window.scrollTo({top:w}):h.scrollTop=w,{direction:c,...ne(p)}}},{name:"page.click",description:"Click an element from page.snapshot (ref + generation). The visitor approves every click.",sensitivity:"mutate",parameters:{type:"object",properties:{ref:Z,generation:X},required:["ref","generation"],additionalProperties:!1},handler:c=>{let u=o(c);if(se(u))throw new Error(`Ref "${c.ref}" is disabled`);return u.scrollIntoView?.({block:"center",inline:"nearest"}),u instanceof HTMLElement?(u.focus({preventScroll:!0}),u.click()):u.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0,composed:!0})),{ref:c.ref,clicked:te(u)}}},{name:"page.fill",description:"Replace the value of a text field, textarea, select (option value or label) or editable area from page.snapshot (ref + generation). The visitor approves every fill.",sensitivity:"mutate",parameters:{type:"object",properties:{ref:Z,generation:X,text:{type:"string",maxLength:1e4}},required:["ref","generation","text"],additionalProperties:!1},handler:c=>{let u=o(c);if(se(u)||u.readOnly)throw new Error(`Ref "${c.ref}" is not editable`);return it(u,c.text),{ref:c.ref,value:L(Le(u),oe)}}}],target:c=>{try{return te(o(c))}catch{return}}}}function it(t,s){if(t instanceof HTMLInputElement){if(Xe.has(t.type))throw new Error(`Inputs of type "${t.type}" cannot be filled; use page.click`);ee(HTMLInputElement.prototype,t,s)}else if(t instanceof HTMLTextAreaElement)ee(HTMLTextAreaElement.prototype,t,s);else if(t instanceof HTMLSelectElement){let e=[...t.options].find(n=>n.value===s)??[...t.options].find(n=>k(n.textContent).toLowerCase()===k(s).toLowerCase());if(!e)throw new Error(`No option "${L(s,oe)}"`);ee(HTMLSelectElement.prototype,t,e.value)}else if(t instanceof HTMLElement&&t.isContentEditable){t.focus({preventScroll:!0}),t.textContent=s,t.dispatchEvent(new InputEvent("input",{bubbles:!0,composed:!0,inputType:"insertReplacementText",data:s}));return}else throw new Error("This element cannot be filled; use page.click");t.focus({preventScroll:!0}),t.dispatchEvent(new Event("input",{bubbles:!0,composed:!0})),t.dispatchEvent(new Event("change",{bubbles:!0}))}function ee(t,s,e){let n=Object.getOwnPropertyDescriptor(t,"value")?.set;n?n.call(s,e):s.value=e}function Le(t){return t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement?t.value:k(t.textContent)}function se(t){return t.disabled===!0||t.closest("fieldset[disabled]")!==null||t.getAttribute("aria-disabled")==="true"}function st(t){if(t instanceof HTMLInputElement&&t.type==="password")return!0;if(!(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement))return!1;if(et.test(t.getAttribute("autocomplete")??""))return!0;let s=[t.name,t.id,t.getAttribute("aria-label"),t.placeholder].filter(Boolean).join(" ");return tt.test(s)}function ot(t){if(t instanceof HTMLInputElement&&t.type==="hidden"||t.closest("[hidden],[inert],[aria-hidden=true]"))return!1;for(let s=t;s;s=s.parentElement){let e=getComputedStyle(s);if(e.display==="none"||s===t&&(e.visibility==="hidden"||e.visibility==="collapse"))return!1}return!0}function rt(t){let s=t.getAttribute("role");if(s)return s;let e=t.tagName.toLowerCase();if(e==="a")return"link";if(e==="select")return"combobox";if(e==="textarea")return"textbox";if(e==="summary")return"button";if(t instanceof HTMLInputElement){let n=t.type;return n==="checkbox"||n==="radio"?n:n==="submit"||n==="button"||n==="reset"||n==="image"?"button":n==="search"?"searchbox":n==="range"?"slider":n==="text"?"textbox":`textbox:${n}`}return t.isContentEditable?"textbox":e}function at(t){let s=t.getAttribute("aria-labelledby");if(s){let o=s.split(/\s+/).map(r=>k(document.getElementById(r)?.textContent)).filter(Boolean).join(" ");if(o)return o}let e=k(t.getAttribute("aria-label"));if(e)return e;let n=t.labels;if(n?.length){let o=k([...n].map(r=>r.textContent).join(" "));if(o)return o}return t instanceof HTMLInputElement&&["submit","button","reset"].includes(t.type)?k(t.value):(t instanceof HTMLSelectElement||t instanceof HTMLTextAreaElement||t instanceof HTMLInputElement?"":k(t.textContent))||k(t.getAttribute("placeholder"))||k(t.getAttribute("title"))||k(t.querySelector("img[alt]")?.getAttribute("alt"))||k(t.getAttribute("name"))}function te(t){let s=[rt(t),JSON.stringify(L(at(t),ie))];if(t instanceof HTMLInputElement&&(t.type==="checkbox"||t.type==="radio"))s.push(t.checked?"checked":"unchecked");else if(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){let e=Le(t);e&&!(t instanceof HTMLInputElement&&["submit","button","reset"].includes(t.type))&&s.push(`value=${JSON.stringify(L(e,oe))}`)}return t instanceof HTMLAnchorElement&&s.push(`href=${JSON.stringify(L(t.getAttribute("href")??"",ie))}`),se(t)&&s.push("disabled"),s.join(" ")}function Re(t){return t===document.body||t===document.documentElement?null:t.scrollHeight>t.clientHeight?t:null}function ne(t){let s=Re(t);return s===null?{scrollY:Math.round(window.scrollY),maxScrollY:Math.max(0,Math.round(document.documentElement.scrollHeight-window.innerHeight))}:{scrollY:Math.round(s.scrollTop),maxScrollY:Math.max(0,Math.round(s.scrollHeight-s.clientHeight))}}function $(t){let s=()=>{throw new Error("Job access is unavailable")};if(!t||typeof t!="object"||Array.isArray(t))return s();let e=t;if(typeof e.bootstrap_url!="string"||typeof e.launch_token!="string"||!/^[A-Za-z0-9_.-]{16,16384}$/.test(e.launch_token)||typeof e.expires_at!="string")return s();let n;try{n=new URL(e.bootstrap_url)}catch{return s()}if(n.protocol!=="https:"||n.username||n.password||n.search||n.hash||n.pathname!=="/identity/job-access/launch"||n.href!==e.bootstrap_url)return s();let i=Date.parse(e.expires_at);return!Number.isFinite(i)||i<=Date.now()||i>Date.now()+6e4?s():{bootstrap_url:n.href,launch_token:e.launch_token,expires_at:e.expires_at}}var ct=new Set(["LINK_EXPIRED","LINK_REVOKED"]),lt=6e4,ae=["content-type","authorization",J,V],E=class extends Error{constructor(e,n,i,o,r){super(e);g(this,"status",n);g(this,"code",i);g(this,"remediation",o);g(this,"retryAfterMs",r)}};function dt(t,s){if(typeof t=="number"&&Number.isFinite(t)&&t>0)return t;let e=Number(s.headers.get("retry-after"));return Number.isFinite(e)&&e>0?e*1e3:void 0}var Me=t=>({get(s){try{return t().getItem(s)}catch{return null}},set(s,e){try{t().setItem(s,e)}catch{}},del(s){try{t().removeItem(s)}catch{}}}),re=Me(()=>localStorage),I=Me(()=>sessionStorage),R=class{constructor(s){g(this,"o",s);g(this,"session",null);g(this,"config",null);g(this,"sessionPromise",null);g(this,"refreshAt",new WeakMap)}url(s,e){let n=this.o.endpoint.replace(/\/+$/,""),i=e?"?"+new URLSearchParams(e).toString():"";return`${n}/${s}${i}`}get storageKey(){return`dewee-webchat:session:${this.o.endpoint}`}get reuseKey(){return`dewee-webchat:reuse:${this.o.endpoint}`}reuseHint(){return I.get(this.reuseKey)}request(s,e){return(this.o.fetch??globalThis.fetch)(s,e)}async headers(s=!1){let e={},n=typeof this.o.headers=="function"?await this.o.headers():this.o.headers;for(let[i,o]of Object.entries(n??{}))typeof o=="string"&&!ae.includes(i.toLowerCase())&&(e[i.toLowerCase()]=o);if(e["content-type"]="application/json",this.o.gatewayUrl&&this.o.gatewayToken&&(e[J]=this.o.gatewayUrl,e[V]=this.o.gatewayToken),s){let i=this.session&&this.fresh(this.session)?this.session:await this.ensureSession();e.authorization=`Bearer ${i.token}`}return e}async parse(s){let e=await s.json().catch(()=>({}));if(!s.ok){let n=e?.error?.remediation,i=n&&typeof n.action=="string"&&typeof n.audience=="string"?{action:n.action,audience:n.audience}:void 0;throw new E(e?.error?.message||`HTTP ${s.status}`,s.status,e?.error?.code,i,dt(e?.error?.retryAfterMs,s))}return e}async getConfig(s=!1){return this.config&&!s?this.config:(this.config=await this.parse(await this.request(this.url("config"),{headers:await this.headers()})),this.config)}fresh(s){if(s.verified)return Date.now()<(this.refreshAt.get(s)??0);let e=typeof s.expiresIn=="number"&&s.expiresIn>=0&&s.obtainedAt,n=e?s.obtainedAt+s.expiresIn:s.expiresAt,i=e?s.expiresIn:s.obtainedAt?s.expiresAt-s.obtainedAt:1/0,o=Math.min(864e5,Math.max(3e4,i*.1));return n-Date.now()>o}scheduleRefresh(s,e){let n=typeof s.expiresIn=="number"&&s.expiresIn>0?s.expiresIn:s.expiresAt-e;this.refreshAt.set(s,e+n-Math.min(lt,n/2))}stored(){let s=re.get(this.storageKey);if(!s)return null;try{let e=JSON.parse(s);return e.verified?null:e}catch{return null}}visitorId(){return this.session?.visitorId??null}ensureSession(){return this.session&&this.fresh(this.session)?Promise.resolve(this.session):this.sessionPromise??(this.sessionPromise=this.loadSession().finally(()=>this.sessionPromise=null))}async loadSession(){if(!this.session){let s=this.stored();if(s){if(this.fresh(s)&&!(await this.getConfig()).identity)return this.session=s;this.session=s}}return this.createSession()}async createSession(){let s=await this.getConfig(),e={},n=this.session&&!this.session.verified?this.session:this.stored();if(n?.token&&(e.token=n.token),s.identity){let l=this.session?.verified?this.session.reuseHint:I.get(this.reuseKey);l&&(e.reuseHint=l)}let i=async()=>this.parse(await this.request(this.url("session"),{method:"POST",headers:await this.headers(),body:JSON.stringify(e)})),o=async()=>{if(!this.o.turnstile)throw new E("Verification is required but no Turnstile handler is set",403,"turnstile_required");e.turnstileToken=await this.o.turnstile(s.turnstileSiteKey)},r;try{s.turnstileSiteKey&&!(s.refreshWithoutTurnstile&&!s.identity&&e.token&&!e.reuseHint)&&await o();try{r=await i()}catch(l){if(!(s.turnstileSiteKey&&!e.turnstileToken&&l instanceof E&&l.code==="turnstile_failed"))throw l;await o(),r=await i()}}catch(l){throw l instanceof E&&l.status===401&&I.del(this.reuseKey),l}let a=Date.now(),d={...r,obtainedAt:a};if(this.session=d,d.verified)this.scheduleRefresh(d,a),typeof d.reuseHint=="string"&&d.reuseHint!==""?I.set(this.reuseKey,d.reuseHint):I.del(this.reuseKey);else{I.del(this.reuseKey);let{reuseHint:l,...c}=d;re.set(this.storageKey,JSON.stringify(c))}return d}forgetSession(){if(this.session?.verified){I.del(this.reuseKey),this.session=null;return}this.session=null,re.del(this.storageKey)}async renewSession(){return this.session=null,this.ensureSession()}async jobAccess(s){try{if(!(await this.ensureSession()).verified)throw new E("Sign in to open job access",401,"IDENTITY_REQUIRED");if(s.aborted)throw new E("Job access was cancelled",0,"job_access_unavailable");let n=await this.request(this.url("job-access"),{method:"POST",headers:await this.headers(!0),body:"{}",signal:s,redirect:"error"});return $(await this.parse(n))}catch(e){let n=e instanceof E&&typeof e.code=="string"&&["IDENTITY_REQUIRED","LINK_EXPIRED","LINK_REVOKED","PERMISSION_DENIED","SOURCE_UNAVAILABLE"].includes(e.code)?e.code:"job_access_unavailable";throw new E("Job access is unavailable. Sign in again or retry.",e instanceof E?e.status:0,n)}}async link(){let s=await this.signedInRequest(async()=>this.request(this.url("link"),{method:"POST",headers:await this.headers(!0),body:"{}"}));return this.parse(s)}async history(s,e){let n=await this.signedInRequest(async()=>this.request(this.url("history",{agent:s,conversationId:e}),{headers:await this.headers(!0)}));return(await this.parse(n)).messages}async signedInRequest(s){await this.ensureSession();let e=await s();return e.status!==401||!this.session?.verified?e:(this.forgetSession(),await this.ensureSession(),s())}async chat(s,e,n){await this.ensureSession();let i=await this.request(this.url("chat"),{method:"POST",headers:await this.headers(!0),body:JSON.stringify(s),signal:n});if(i.status===401){let d=this.visitorId();this.forgetSession(),await this.ensureSession(),s.actionsHash&&this.visitorId()!==d&&(s={...s,actionsHash:void 0}),i=await this.request(this.url("chat"),{method:"POST",headers:await this.headers(!0),body:JSON.stringify(s),signal:n})}(!i.ok||!i.body)&&await this.parse(i);let o=i.body.pipeThrough(new TextDecoderStream).getReader(),r="",a=!1;for(;;){let{done:d,value:l}=await o.read();if(d)break;r+=l;let c;for(;(c=r.indexOf(`
16
+ `).slice(0,s)}function ee(t){if(t!==void 0)try{let s=JSON.stringify(t);return s===void 0?null:JSON.parse(s)}catch{return"[unserializable result]"}}var te=t=>t===null?"null":Array.isArray(t)?"array":typeof t=="number"?Number.isInteger(t)?"integer":"number":typeof t,ot=(t,s)=>{let e=te(t);return e===s||s==="number"&&e==="integer"};function j(t,s,e="args",n=0){if(!s||typeof s!="object")return null;if(n>32)return`${e}: schema is nested too deeply`;let i=s;if(i.type!==void 0){let r=Array.isArray(i.type)?i.type:[i.type];if(!r.some(o=>ot(t,o)))return`${e}: expected ${r.join(" or ")}, got ${te(t)}`}if(Array.isArray(i.enum)&&!i.enum.some(r=>Ie(r,t)))return`${e}: must be one of ${i.enum.map(r=>JSON.stringify(r)).join(", ")}`;if("const"in i&&!Ie(i.const,t))return`${e}: must equal ${JSON.stringify(i.const)}`;if(typeof t=="string"){if(typeof i.minLength=="number"&&t.length<i.minLength)return`${e}: shorter than ${i.minLength} characters`;if(typeof i.maxLength=="number"&&t.length>i.maxLength)return`${e}: longer than ${i.maxLength} characters`;if(typeof i.pattern=="string"){let r=null;try{r=new RegExp(i.pattern,"u")}catch{return`${e}: schema pattern is invalid`}if(!r.test(t))return`${e}: does not match ${i.pattern}`}}if(typeof t=="number"){if(typeof i.minimum=="number"&&t<i.minimum)return`${e}: must be >= ${i.minimum}`;if(typeof i.maximum=="number"&&t>i.maximum)return`${e}: must be <= ${i.maximum}`}if(Array.isArray(t)){if(typeof i.minItems=="number"&&t.length<i.minItems)return`${e}: needs at least ${i.minItems} items`;if(typeof i.maxItems=="number"&&t.length>i.maxItems)return`${e}: allows at most ${i.maxItems} items`;if(i.items&&typeof i.items=="object")for(let r=0;r<t.length;r++){let o=j(t[r],i.items,`${e}[${r}]`,n+1);if(o)return o}}if(te(t)==="object"){let r=t,o=i.properties&&typeof i.properties=="object"?i.properties:{};for(let c of Array.isArray(i.required)?i.required:[])if(!(c in r))return`${e}.${c}: is required`;for(let[c,a]of Object.entries(r))if(Object.prototype.hasOwnProperty.call(o,c)){let d=j(a,o[c],`${e}.${c}`,n+1);if(d)return d}else if(i.additionalProperties===!1)return`${e}.${c}: is not allowed`}return null}function Ie(t,s){return JSON.stringify(t)===JSON.stringify(s)}var Pe=/^[a-z][a-z0-9_.-]{0,63}$/,ne=["read","navigate","mutate","destructive"],S={maxActions:32,maxDescription:1e3,maxParametersBytes:4096,maxManifestBytes:16384,maxPageContextBytes:4096},at="[[dewee-page v1]]",Le="[[/dewee-page]]";function ie(t){if(!t.startsWith(at))return t;let s=t.indexOf(`
17
+ `+Le);return s<0?t:t.slice(s+Le.length+1).replace(/^\n+/,"")}var ct=t=>t==="mutate"||t==="destructive",O=class{constructor(){f(this,"map",new Map)}get size(){return this.map.size}get(s){return this.map.get(s)}names(){return[...this.map.keys()]}register(s){let e=Array.isArray(s)?s:[s];for(let n of e)lt(n);if(new Set([...this.map.keys(),...e.map(n=>n.name)]).size>S.maxActions)throw new TypeError(`dewee-webchat: at most ${S.maxActions} page actions`);for(let n of e)this.map.set(n.name,n)}unregister(s){return this.map.delete(s)}manifest(){return[...this.map.values()].map(s=>({name:s.name,description:s.description,sensitivity:s.sensitivity,parameters:s.parameters??{type:"object",properties:{}}}))}};function lt(t){let s=e=>{throw new TypeError(`dewee-webchat: invalid page action ${JSON.stringify(t?.name)}: ${e}`)};(!t||typeof t!="object")&&s("not an object"),(typeof t.name!="string"||!Pe.test(t.name))&&s("name must match ^[a-z][a-z0-9_.-]{0,63}$"),(typeof t.description!="string"||t.description.length>S.maxDescription)&&s(`description must be a string up to ${S.maxDescription} chars`),ne.includes(t.sensitivity)||s(`sensitivity must be one of ${ne.join(", ")}`),typeof t.handler!="function"&&s("handler must be a function"),t.parameters!==void 0&&(typeof t.parameters!="object"||t.parameters===null||Array.isArray(t.parameters))&&s("parameters must be a JSON Schema object")}async function Re(t,s){let e=a=>(s.onStatus?.("error"),{id:t.id,name:t.name,status:"error",error:a});if(!t.ok)return e(t.error);if(s.signal.aborted)return e("Cancelled");let n=s.registry.get(t.name);if(!n)return e(`Unknown action "${t.name}". Available: ${s.registry.names().join(", ")||"none"}`);let i=j(t.args,n.parameters??{type:"object"});if(i)return e(`Invalid arguments: ${i}`);if(ct(n.sensitivity)){s.onStatus?.("awaiting-confirmation");let{handler:a,...d}=n,l=!1;try{l=await Me(Promise.resolve(s.confirm({...d,callId:t.id},t.args)),s.signal)===!0}catch{l=!1}if(!l||s.signal.aborted)return s.onStatus?.("denied"),{id:t.id,name:t.name,status:"denied",error:"The user declined this action."}}s.onStatus?.("running");let r=new AbortController,o=()=>r.abort();s.signal.addEventListener("abort",o,{once:!0});let c=setTimeout(o,s.timeoutMs??3e4);try{let a=await Me(Promise.resolve().then(()=>n.handler(t.args,{callId:t.id,conversationId:s.conversationId,agent:s.agent,signal:r.signal})),r.signal);return s.onStatus?.("done"),{id:t.id,name:t.name,status:"ok",result:ee(a)??null}}catch(a){return e(r.signal.aborted?s.signal.aborted?"Cancelled":"Timed out":String(a?.message??a).slice(0,500)||"Action failed")}finally{clearTimeout(c),s.signal.removeEventListener("abort",o)}}function Me(t,s){return s.aborted?Promise.reject(new Error("aborted")):new Promise((e,n)=>{let i=()=>n(new Error("aborted"));s.addEventListener("abort",i,{once:!0}),t.then(e,n).finally(()=>s.removeEventListener("abort",i))})}var _e=["page.snapshot","page.scroll","page.click","page.fill"],dt=["a[href]","button","input","select","textarea","summary","[contenteditable]:not([contenteditable=false])",...["button","link","checkbox","radio","switch","tab","menuitem","option","combobox","textbox","searchbox"].map(t=>`[role=${t}]`)].join(","),pt=new Set(["checkbox","radio","file","submit","button","image","reset","hidden","password"]),ht=/\b(cc-[a-z-]+|one-time-code|current-password|new-password)\b/i,ut=/(passw|passcode|\bpin\b|otp|one.?time|cvv|cvc|card.?(num|no)|cc.?num|security.?code|\bssn\b)/i,le=80,pe=60,gt=40,P=(t,s)=>t.length>s?t.slice(0,s-1)+"\u2026":t,k=t=>(t??"").replace(/\s+/g," ").trim(),se={type:"string",pattern:"^e[0-9]{1,4}$"},re={type:"integer",minimum:1};function Ne(t){let s=0,e=new Map,n=()=>{let l=t.root(),p=typeof l=="string"?document.querySelector(l):l;if(l!==void 0&&!p)throw new Error(`domActionsRoot ${JSON.stringify(l)} matches no element`);return p??document.body},i=(l,p)=>l.isConnected&&p.contains(l)&&!t.exclude?.(l)&&!l.closest("[data-dewee-ignore]")&&!mt(l)&&bt(l),r=l=>{if(l.generation!==s)throw new Error(`Stale ref: generation ${l.generation} is not the latest snapshot (${s||"none"}). Call page.snapshot again.`);let p=e.get(l.ref);if(!p)throw new Error(`Unknown ref "${l.ref}". Call page.snapshot again.`);if(!i(p,n()))throw new Error(`Ref "${l.ref}" is no longer available. Call page.snapshot again.`);return p};return{actions:[{name:"page.snapshot",description:'List the interactive elements visible on the page (links, buttons, form fields) as lines `ref role "name" [state]`. Use the ref together with the returned generation in page.scroll, page.click and page.fill. Every snapshot invalidates older refs. Use query to filter by visible name, offset/limit to page through long lists.',sensitivity:"read",parameters:{type:"object",properties:{query:{type:"string",maxLength:100},offset:{type:"integer",minimum:0},limit:{type:"integer",minimum:1,maximum:100}},additionalProperties:!1},handler:({query:l,offset:p=0,limit:g=gt})=>{let h=n();s++,e=new Map;let u=k(l).toLowerCase(),m=[],b=0;for(let x of h.querySelectorAll(dt)){if(!i(x,h))continue;let w=ae(x);if(u&&!w.toLowerCase().includes(u)||(b++,b<=p||m.length>=g))continue;let y=`e${b}`;e.set(y,x),m.push(`${y} ${w}`)}return{generation:s,url:location.pathname+location.search,title:P(document.title,le),total:b,offset:p,elements:m,...ce(h)}}},{name:"page.scroll",description:"Scroll the page by about one screen (direction up/down) or to the top/bottom, or scroll an element from page.snapshot into view (ref + generation).",sensitivity:"read",parameters:{type:"object",properties:{direction:{type:"string",enum:["up","down","top","bottom"]},ref:se,generation:re},additionalProperties:!1},handler:({direction:l,ref:p,generation:g})=>{let h=n();if(p!==void 0){if(g===void 0)throw new Error("generation is required with ref");return r({ref:p,generation:g}).scrollIntoView?.({block:"center",inline:"nearest"}),{ref:p,...ce(h)}}if(!l)throw new Error("Give a direction or a ref");let u=He(h),m=u===null?window.innerHeight:u.clientHeight,b=u===null?window.scrollY:u.scrollTop,x=u===null?document.documentElement.scrollHeight:u.scrollHeight,w=l==="top"?0:l==="bottom"?x:b+(l==="down"?.8:-.8)*m;return u===null?window.scrollTo({top:w}):u.scrollTop=w,{direction:l,...ce(h)}}},{name:"page.click",description:"Click an element from page.snapshot (ref + generation). The visitor approves every click.",sensitivity:"mutate",parameters:{type:"object",properties:{ref:se,generation:re},required:["ref","generation"],additionalProperties:!1},handler:l=>{let p=r(l);if(de(p))throw new Error(`Ref "${l.ref}" is disabled`);return p.scrollIntoView?.({block:"center",inline:"nearest"}),p instanceof HTMLElement?(p.focus({preventScroll:!0}),p.click()):p.dispatchEvent(new MouseEvent("click",{bubbles:!0,cancelable:!0,composed:!0})),{ref:l.ref,clicked:ae(p)}}},{name:"page.fill",description:"Replace the value of a text field, textarea, select (option value or label) or editable area from page.snapshot (ref + generation). The visitor approves every fill.",sensitivity:"mutate",parameters:{type:"object",properties:{ref:se,generation:re,text:{type:"string",maxLength:1e4}},required:["ref","generation","text"],additionalProperties:!1},handler:l=>{let p=r(l);if(de(p)||p.readOnly)throw new Error(`Ref "${l.ref}" is not editable`);return ft(p,l.text),{ref:l.ref,value:P(Oe(p),pe)}}}],target:l=>{try{return ae(r(l))}catch{return}}}}function ft(t,s){if(t instanceof HTMLInputElement){if(pt.has(t.type))throw new Error(`Inputs of type "${t.type}" cannot be filled; use page.click`);oe(HTMLInputElement.prototype,t,s)}else if(t instanceof HTMLTextAreaElement)oe(HTMLTextAreaElement.prototype,t,s);else if(t instanceof HTMLSelectElement){let e=[...t.options].find(n=>n.value===s)??[...t.options].find(n=>k(n.textContent).toLowerCase()===k(s).toLowerCase());if(!e)throw new Error(`No option "${P(s,pe)}"`);oe(HTMLSelectElement.prototype,t,e.value)}else if(t instanceof HTMLElement&&t.isContentEditable){t.focus({preventScroll:!0}),t.textContent=s,t.dispatchEvent(new InputEvent("input",{bubbles:!0,composed:!0,inputType:"insertReplacementText",data:s}));return}else throw new Error("This element cannot be filled; use page.click");t.focus({preventScroll:!0}),t.dispatchEvent(new Event("input",{bubbles:!0,composed:!0})),t.dispatchEvent(new Event("change",{bubbles:!0}))}function oe(t,s,e){let n=Object.getOwnPropertyDescriptor(t,"value")?.set;n?n.call(s,e):s.value=e}function Oe(t){return t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement?t.value:k(t.textContent)}function de(t){return t.disabled===!0||t.closest("fieldset[disabled]")!==null||t.getAttribute("aria-disabled")==="true"}function mt(t){if(t instanceof HTMLInputElement&&t.type==="password")return!0;if(!(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement))return!1;if(ht.test(t.getAttribute("autocomplete")??""))return!0;let s=[t.name,t.id,t.getAttribute("aria-label"),t.placeholder].filter(Boolean).join(" ");return ut.test(s)}function bt(t){if(t instanceof HTMLInputElement&&t.type==="hidden"||t.closest("[hidden],[inert],[aria-hidden=true]"))return!1;for(let s=t;s;s=s.parentElement){let e=getComputedStyle(s);if(e.display==="none"||s===t&&(e.visibility==="hidden"||e.visibility==="collapse"))return!1}return!0}function wt(t){let s=t.getAttribute("role");if(s)return s;let e=t.tagName.toLowerCase();if(e==="a")return"link";if(e==="select")return"combobox";if(e==="textarea")return"textbox";if(e==="summary")return"button";if(t instanceof HTMLInputElement){let n=t.type;return n==="checkbox"||n==="radio"?n:n==="submit"||n==="button"||n==="reset"||n==="image"?"button":n==="search"?"searchbox":n==="range"?"slider":n==="text"?"textbox":`textbox:${n}`}return t.isContentEditable?"textbox":e}function yt(t){let s=t.getAttribute("aria-labelledby");if(s){let r=s.split(/\s+/).map(o=>k(document.getElementById(o)?.textContent)).filter(Boolean).join(" ");if(r)return r}let e=k(t.getAttribute("aria-label"));if(e)return e;let n=t.labels;if(n?.length){let r=k([...n].map(o=>o.textContent).join(" "));if(r)return r}return t instanceof HTMLInputElement&&["submit","button","reset"].includes(t.type)?k(t.value):(t instanceof HTMLSelectElement||t instanceof HTMLTextAreaElement||t instanceof HTMLInputElement?"":k(t.textContent))||k(t.getAttribute("placeholder"))||k(t.getAttribute("title"))||k(t.querySelector("img[alt]")?.getAttribute("alt"))||k(t.getAttribute("name"))}function ae(t){let s=[wt(t),JSON.stringify(P(yt(t),le))];if(t instanceof HTMLInputElement&&(t.type==="checkbox"||t.type==="radio"))s.push(t.checked?"checked":"unchecked");else if(t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){let e=Oe(t);e&&!(t instanceof HTMLInputElement&&["submit","button","reset"].includes(t.type))&&s.push(`value=${JSON.stringify(P(e,pe))}`)}return t instanceof HTMLAnchorElement&&s.push(`href=${JSON.stringify(P(t.getAttribute("href")??"",le))}`),de(t)&&s.push("disabled"),s.join(" ")}function He(t){return t===document.body||t===document.documentElement?null:t.scrollHeight>t.clientHeight?t:null}function ce(t){let s=He(t);return s===null?{scrollY:Math.round(window.scrollY),maxScrollY:Math.max(0,Math.round(document.documentElement.scrollHeight-window.innerHeight))}:{scrollY:Math.round(s.scrollTop),maxScrollY:Math.max(0,Math.round(s.scrollHeight-s.clientHeight))}}function B(t){let s=()=>{throw new Error("Job access is unavailable")};if(!t||typeof t!="object"||Array.isArray(t))return s();let e=t;if(typeof e.bootstrap_url!="string"||typeof e.launch_token!="string"||!/^[A-Za-z0-9_.-]{16,16384}$/.test(e.launch_token)||typeof e.expires_at!="string")return s();let n;try{n=new URL(e.bootstrap_url)}catch{return s()}if(n.protocol!=="https:"||n.username||n.password||n.search||n.hash||n.pathname!=="/identity/job-access/launch"||n.href!==e.bootstrap_url)return s();let i=Date.parse(e.expires_at);return!Number.isFinite(i)||i<=Date.now()||i>Date.now()+6e4?s():{bootstrap_url:n.href,launch_token:e.launch_token,expires_at:e.expires_at}}var xt=new Set(["LINK_EXPIRED","LINK_REVOKED"]),vt=6e4,he=["content-type","authorization",W,F],E=class extends Error{constructor(e,n,i,r,o){super(e);f(this,"status",n);f(this,"code",i);f(this,"remediation",r);f(this,"retryAfterMs",o)}};function Et(t,s){if(typeof t=="number"&&Number.isFinite(t)&&t>0)return t;let e=Number(s.headers.get("retry-after"));return Number.isFinite(e)&&e>0?e*1e3:void 0}var De=t=>({get(s){try{return t().getItem(s)}catch{return null}},set(s,e){try{t().setItem(s,e)}catch{}},del(s){try{t().removeItem(s)}catch{}}}),z=De(()=>localStorage),L=De(()=>sessionStorage),M=class{constructor(s){f(this,"o",s);f(this,"session",null);f(this,"config",null);f(this,"sessionPromise",null);f(this,"supersededSessions",new Map);f(this,"sessionGeneration",0);f(this,"refreshAt",new WeakMap)}url(s,e){let n=this.o.endpoint.replace(/\/+$/,""),i=e?"?"+new URLSearchParams(e).toString():"";return`${n}/${s}${i}`}get storageKey(){return`dewee-webchat:session:${this.o.endpoint}`}get reuseKey(){return`dewee-webchat:reuse:${this.o.endpoint}`}reuseHint(){return L.get(this.reuseKey)}request(s,e){return(this.o.fetch??globalThis.fetch)(s,e)}async headers(s=!1){let e={},n=typeof this.o.headers=="function"?await this.o.headers():this.o.headers;for(let[i,r]of Object.entries(n??{}))typeof r=="string"&&!he.includes(i.toLowerCase())&&(e[i.toLowerCase()]=r);if(e["content-type"]="application/json",this.o.gatewayUrl&&this.o.gatewayToken&&(e[W]=this.o.gatewayUrl,e[F]=this.o.gatewayToken),s){let i=await this.ensureSession();e.authorization=`Bearer ${i.token}`}return e}async parse(s){let e=await s.json().catch(()=>({}));if(!s.ok){let n=e?.error?.remediation,i=n&&typeof n.action=="string"&&typeof n.audience=="string"?{action:n.action,audience:n.audience}:void 0;throw new E(e?.error?.message||`HTTP ${s.status}`,s.status,e?.error?.code,i,Et(e?.error?.retryAfterMs,s))}return e}async imageUrl(s,e){let n=await this.request(this.url("image-ticket"),{method:"POST",headers:await this.headers(!0),body:JSON.stringify({url:s}),redirect:"error",signal:e}),i=await this.parse(n);if(typeof i.ticket!="string"||!/^[A-Za-z0-9_-]{1,8192}$/.test(i.ticket))throw new Error("Invalid image ticket");return this.url("image",{ticket:i.ticket})}async getConfig(s=!1,e=!1){return this.config&&!s?this.config:(this.config=await this.parse(await this.request(this.url("config",e?{pageContext:"1"}:void 0),{headers:await this.headers()})),this.config)}fresh(s){if(s.verified)return Date.now()<(this.refreshAt.get(s)??0);let e=typeof s.expiresIn=="number"&&s.expiresIn>=0&&s.obtainedAt,n=e?s.obtainedAt+s.expiresIn:s.expiresAt,i=e?s.expiresIn:s.obtainedAt?s.expiresAt-s.obtainedAt:1/0,r=Math.min(864e5,i/2,Math.max(3e4,i*.1));return n-Date.now()>r}scheduleRefresh(s,e){let n=typeof s.expiresIn=="number"&&s.expiresIn>0?s.expiresIn:s.expiresAt-e;this.refreshAt.set(s,e+n-Math.min(vt,n/2))}stored(){let s=z.get(this.storageKey);if(!s)return null;try{let e=JSON.parse(s);return e.verified?(z.del(this.storageKey),null):e}catch{return null}}visitorId(){return this.session?.visitorId??null}ensureSession(){if(this.sessionPromise)return this.sessionPromise;if(this.session&&this.fresh(this.session))return Promise.resolve(this.session);let s=this.sessionGeneration,e=this.loadSession(s).catch(n=>{if(s!==this.sessionGeneration)return this.supersededSessions.get(s);throw n}).finally(()=>{this.sessionPromise===e&&(this.sessionPromise=null),this.supersededSessions.delete(s)});return this.sessionPromise=e}async loadSession(s){if(!this.session){let e=this.stored();if(e){if(this.fresh(e)){let n=await this.getConfig();if(s!==this.sessionGeneration)return this.supersededSessions.get(s);if(!n.identity)return this.session=e}this.session=e}}return this.createSession(s)}async createSession(s){let e=await this.getConfig();if(s!==this.sessionGeneration)return this.supersededSessions.get(s);let n={},i=this.session&&!this.session.verified?this.session:this.stored();if(i?.token&&(n.token=i.token),e.identity){let l=this.session?.verified?this.session.reuseHint:L.get(this.reuseKey);l&&(n.reuseHint=l)}let r=async()=>this.parse(await this.request(this.url("session"),{method:"POST",headers:await this.headers(),body:JSON.stringify(n)})),o=async()=>{if(!this.o.turnstile)throw new E("Verification is required but no Turnstile handler is set",403,"turnstile_required");n.turnstileToken=await this.o.turnstile(e.turnstileSiteKey)},c;try{e.turnstileSiteKey&&!(e.refreshWithoutTurnstile&&!e.identity&&n.token&&!n.reuseHint)&&await o();try{c=await r()}catch(l){if(!(e.turnstileSiteKey&&!n.turnstileToken&&l instanceof E&&l.code==="turnstile_failed"))throw l;await o(),c=await r()}}catch(l){if(s!==this.sessionGeneration)return this.supersededSessions.get(s);throw this.session=null,l instanceof E&&l.status===401&&L.del(this.reuseKey),l}if(s!==this.sessionGeneration)return this.supersededSessions.get(s);let a=Date.now(),d={...c,obtainedAt:a};if(this.session=d,d.verified)this.scheduleRefresh(d,a),typeof d.reuseHint=="string"&&d.reuseHint!==""?L.set(this.reuseKey,d.reuseHint):L.del(this.reuseKey);else{L.del(this.reuseKey);let{reuseHint:l,...p}=d;z.set(this.storageKey,JSON.stringify(p))}return d}forgetSession(){if(this.session?.verified){L.del(this.reuseKey),this.session=null;return}this.session=null,z.del(this.storageKey)}async renewSession(){let s=this.sessionGeneration,e=this.sessionPromise;this.sessionGeneration++,this.session=null,this.sessionPromise=null;let n=this.ensureSession();return e&&this.supersededSessions.set(s,n),n}async jobAccess(s){try{if(!(await this.ensureSession()).verified)throw new E("Sign in to open job access",401,"IDENTITY_REQUIRED");if(s.aborted)throw new E("Job access was cancelled",0,"job_access_unavailable");let n=await this.request(this.url("job-access"),{method:"POST",headers:await this.headers(!0),body:"{}",signal:s,redirect:"error"});return B(await this.parse(n))}catch(e){let n=e instanceof E&&typeof e.code=="string"&&["IDENTITY_REQUIRED","LINK_EXPIRED","LINK_REVOKED","PERMISSION_DENIED","SOURCE_UNAVAILABLE"].includes(e.code)?e.code:"job_access_unavailable";throw new E("Job access is unavailable. Sign in again or retry.",e instanceof E?e.status:0,n)}}async link(){let s=await this.signedInRequest(async()=>this.request(this.url("link"),{method:"POST",headers:await this.headers(!0),body:"{}"}));return this.parse(s)}async history(s,e){let n=await this.signedInRequest(async()=>this.request(this.url("history",{agent:s,conversationId:e}),{headers:await this.headers(!0)}));return(await this.parse(n)).messages}async signedInRequest(s){await this.ensureSession();let e=await s();return e.status!==401||!this.session?.verified?e:(this.forgetSession(),await this.ensureSession(),s())}async chat(s,e,n){await this.ensureSession();let i=await this.request(this.url("chat"),{method:"POST",headers:await this.headers(!0),body:JSON.stringify(s),signal:n});if(i.status===401){let a=this.visitorId();this.forgetSession(),await this.ensureSession(),s.actionsHash&&this.visitorId()!==a&&(s={...s,actionsHash:void 0}),i=await this.request(this.url("chat"),{method:"POST",headers:await this.headers(!0),body:JSON.stringify(s),signal:n})}(!i.ok||!i.body)&&await this.parse(i);let r=i.body.pipeThrough(new TextDecoderStream).getReader(),o="",c=!1;for(;;){let{done:a,value:d}=await r.read();if(a)break;o+=d;let l;for(;(l=o.indexOf(`
18
18
 
19
- `))>=0;){let u=r.slice(0,c);r=r.slice(c+2);let f=u.split(`
20
- `).filter(h=>h.startsWith("data:")).map(h=>h.slice(5).trimStart()).join(`
21
- `);if(!f)continue;let p;try{p=JSON.parse(f)}catch{continue}p.type==="error"&&p.code&&ct.has(p.code)&&(a=!0);try{e(p)}catch{}}}a&&this.session?.verified&&(this.forgetSession(),await this.ensureSession().catch(()=>{}))}};var A=class extends Error{constructor(e){super("Job access could not be opened");g(this,"code",e)}};async function _e(t,s){let e=`dewee-job-access-${crypto.randomUUID()}`,n;try{n=window.open("about:blank",e,"popup,width=720,height=800")}catch{throw new A("popup_blocked")}if(!n)throw new A("popup_blocked");let i=new AbortController,o=()=>i.abort(),r,a=new Promise((w,x)=>{r=()=>x(new A(n.closed?"popup_closed":"job_access_unavailable"))});i.signal.addEventListener("abort",r,{once:!0}),s?.addEventListener("abort",o,{once:!0});let d=setTimeout(o,3e4),l=!1,c,u,f=new Promise((w,x)=>{c=w,u=()=>x(new A("job_access_unavailable"))}),p=setInterval(()=>{if(n.closed){o();return}if(l)try{n.location.href!=="about:blank"&&c()}catch{c()}},200);window.addEventListener("pagehide",o,{once:!0});let h,m,b,v=w=>{w.disposition==="enforce"&&(w.effectiveDirective==="form-action"||w.violatedDirective==="form-action")&&u()};try{n.opener=null,s?.aborted&&o();let w=$(await Promise.race([t(i.signal),a]));if(n.closed)throw new A("popup_closed");if(i.signal.aborted)throw new A("job_access_unavailable");b=n.document;let x=b.createElement("meta");x.name="referrer",x.content="strict-origin",b.head.append(x),h=b.createElement("form"),h.method="POST",h.action=w.bootstrap_url,h.target="_self",h.hidden=!0,m=b.createElement("input"),m.type="hidden",m.name="launch_token",m.value=w.launch_token,h.append(m),b.body.append(h),b.addEventListener("securitypolicyviolation",v),HTMLFormElement.prototype.submit.call(h),l=!0,m.value="",w.launch_token="",h.remove(),await Promise.race([f,a])}catch(w){let x=n.closed;try{n.close()}catch{}throw x?new A("popup_closed"):(w instanceof A,w)}finally{m&&(m.value=""),h?.remove(),b?.removeEventListener("securitypolicyviolation",v),clearTimeout(d),clearInterval(p),window.removeEventListener("pagehide",o),s?.removeEventListener("abort",o),i.signal.removeEventListener("abort",r),i.abort()}}var ut=0;function Pe(t,s,e,n,i){let o=`dw-confirm-${++ut}`,r=t.getRootNode(),a=r.activeElement,d=document.createElement("div");d.className="confirm-backdrop",d.innerHTML=`
22
- <div class="confirm" role="alertdialog" aria-modal="true" aria-labelledby="${o}-t" aria-describedby="${o}-d">
23
- <h3 id="${o}-t"></h3>
24
- <div id="${o}-d" class="confirm-desc">
19
+ `))>=0;){let p=o.slice(0,l);o=o.slice(l+2);let g=p.split(`
20
+ `).filter(u=>u.startsWith("data:")).map(u=>u.slice(5).trimStart()).join(`
21
+ `);if(!g)continue;let h;try{h=JSON.parse(g)}catch{continue}h.type==="error"&&h.code&&xt.has(h.code)&&(c=!0);try{e(h)}catch{}}}c&&this.session?.verified&&(this.forgetSession(),await this.ensureSession().catch(()=>{}))}};var A=class extends Error{constructor(e){super("Job access could not be opened");f(this,"code",e)}};async function $e(t,s){let e=`dewee-job-access-${crypto.randomUUID()}`,n;try{n=window.open("about:blank",e,"popup,width=720,height=800")}catch{throw new A("popup_blocked")}if(!n)throw new A("popup_blocked");let i=new AbortController,r=()=>i.abort(),o,c=new Promise((w,y)=>{o=()=>y(new A(n.closed?"popup_closed":"job_access_unavailable"))});i.signal.addEventListener("abort",o,{once:!0}),s?.addEventListener("abort",r,{once:!0});let a=setTimeout(r,3e4),d=!1,l,p,g=new Promise((w,y)=>{l=w,p=()=>y(new A("job_access_unavailable"))}),h=setInterval(()=>{if(n.closed){r();return}if(d)try{n.location.href!=="about:blank"&&l()}catch{l()}},200);window.addEventListener("pagehide",r,{once:!0});let u,m,b,x=w=>{w.disposition==="enforce"&&(w.effectiveDirective==="form-action"||w.violatedDirective==="form-action")&&p()};try{n.opener=null,s?.aborted&&r();let w=B(await Promise.race([t(i.signal),c]));if(n.closed)throw new A("popup_closed");if(i.signal.aborted)throw new A("job_access_unavailable");b=n.document;let y=b.createElement("meta");y.name="referrer",y.content="strict-origin",b.head.append(y),u=b.createElement("form"),u.method="POST",u.action=w.bootstrap_url,u.target="_self",u.hidden=!0,m=b.createElement("input"),m.type="hidden",m.name="launch_token",m.value=w.launch_token,u.append(m),b.body.append(u),b.addEventListener("securitypolicyviolation",x),HTMLFormElement.prototype.submit.call(u),d=!0,m.value="",w.launch_token="",u.remove(),await Promise.race([g,c])}catch(w){let y=n.closed;try{n.close()}catch{}throw y?new A("popup_closed"):(w instanceof A,w)}finally{m&&(m.value=""),u?.remove(),b?.removeEventListener("securitypolicyviolation",x),clearTimeout(a),clearInterval(h),window.removeEventListener("pagehide",r),s?.removeEventListener("abort",r),i.signal.removeEventListener("abort",o),i.abort()}}var kt=0;function je(t,s,e,n,i){let r=`dw-confirm-${++kt}`,o=t.getRootNode(),c=o.activeElement,a=document.createElement("div");a.className="confirm-backdrop",a.innerHTML=`
22
+ <div class="confirm" role="alertdialog" aria-modal="true" aria-labelledby="${r}-t" aria-describedby="${r}-d">
23
+ <h3 id="${r}-t"></h3>
24
+ <div id="${r}-d" class="confirm-desc">
25
25
  <div class="confirm-action"><code></code><span class="sens"></span></div>
26
26
  <p class="confirm-text"></p>
27
27
  <p class="confirm-warn" hidden></p>
@@ -31,12 +31,12 @@
31
31
  <button type="button" class="btn deny"></button>
32
32
  <button type="button" class="btn allow"></button>
33
33
  </div>
34
- </div>`;let l=m=>d.querySelector(m);l("h3").textContent=s.confirmTitle,l("code").textContent=e.name;let c=l(".sens");if(c.textContent=e.sensitivity,c.dataset.level=e.sensitivity,l(".confirm-text").textContent=e.description,e.sensitivity==="destructive"){let m=l(".confirm-warn");m.hidden=!1,m.textContent=s.confirmDestructive}let u=JSON.stringify(n,null,2),f=l(".confirm-args");u&&u!=="{}"?f.textContent=u:f.remove();let p=l(".deny"),h=l(".allow");return p.textContent=s.deny,h.textContent=s.allow,e.sensitivity==="destructive"&&h.classList.add("danger"),new Promise(m=>{let b=!1,v=x=>{b||(b=!0,i?.removeEventListener("abort",w),d.remove(),a?.focus?.(),m(x))},w=()=>v(!1);if(i?.aborted)return v(!1);i?.addEventListener("abort",w,{once:!0}),p.addEventListener("click",()=>v(!1)),h.addEventListener("click",()=>v(!0)),d.addEventListener("keydown",x=>{x.key==="Escape"?(x.preventDefault(),x.stopPropagation(),v(!1)):x.key==="Tab"&&(x.preventDefault(),(r.activeElement===p?h:p).focus())}),t.appendChild(d),p.focus()})}var pt={title:"Assistant",greeting:"Hi there \u{1F44B}",greetingBody:"Ask me anything. I can look things up and use tools to help you.",placeholder:"Type a message\u2026",send:"Send",stop:"Stop",newChat:"New conversation",close:"Close chat",open:"Open chat",thinking:"Thinking\u2026",thoughtFor:t=>`Thought for ${t}s`,reasoning:"Reasoning",toolRunning:"running",toolDone:"done",toolError:"error",args:"Arguments",result:"Result",online:"Online",poweredBy:"Powered by",errorGeneric:"Something went wrong. Please try again.",stopped:"Stopped.",actionStatus:{pending:"queued","awaiting-confirmation":"needs approval",running:"running",done:"done",denied:"declined",error:"failed"},confirmTitle:"Allow this action?",confirmDestructive:"This can't be undone.",allow:"Allow",deny:"Deny",actionLimit:t=>`Stopped after ${t} automatic action rounds. Send a message to continue.`,identityErrors:{IDENTITY_REQUIRED:"Please sign in to chat.",IDENTITY_LINK_REQUIRED:"Link your chat account to continue.",IDENTITY_CONFLICT:"This chat account is already linked to another user. Unlink it there first.",LINK_EXPIRED:"Your session expired. Send your message again.",LINK_REVOKED:"Your access has ended. Sign in again to continue.",PERMISSION_DENIED:"You don't have access to this.",SOURCE_UNAVAILABLE:"We couldn't check your sign-in right now. Please try again shortly."},admissionErrors:{POLICY_DENIED:"This message can't be sent. Try shortening or rephrasing it.",RATE_LIMITED:"You're sending messages too quickly.",CHALLENGE_REQUIRED:"Extra verification is needed. Please try again later."},cooldown:t=>`You can send again in ${t}s`,cooldownStart:t=>`Sending is paused. You can send again in ${t} second${t===1?"":"s"}.`,cooldownOver:"You can send messages again.",linkErrors:{idempotency_key_reused:"This link request was already used. Please try again.",link_in_progress:"A link is already in progress. Use the code you got, or wait for it to expire.",linking_unavailable:"Linking is not available right now. Please try again later."},linkIntro:"Send this code in a direct message from the chat account you want to link:",linkContinueOn:t=>`Continue on ${t}`,linkExpires:t=>`The code expires in ${t} min.`,linkNoTargets:"No chat app is set up for linking yet.",jobAccess:"Job access",jobAccessOpened:"Job access opened in a new window. Review and confirm any permissions there.",jobAccessUnavailable:"Job access could not be opened. Sign in again or retry.",jobAccessPopupBlocked:"Allow popups for this site, then choose Job access again.",jobAccessPopupClosed:"The window was closed. Choose Job access again to retry."},ht={title:"Tr\u1EE3 l\xFD",greeting:"Xin ch\xE0o \u{1F44B}",greetingBody:"B\u1EA1n c\u1EA7n h\u1ECFi g\xEC c\u1EE9 nh\u1EAFn nh\xE9. M\xECnh c\xF3 th\u1EC3 tra c\u1EE9u v\xE0 d\xF9ng c\xF4ng c\u1EE5 \u0111\u1EC3 h\u1ED7 tr\u1EE3 b\u1EA1n.",placeholder:"Nh\u1EADp tin nh\u1EAFn\u2026",send:"G\u1EEDi",stop:"D\u1EEBng",newChat:"Cu\u1ED9c tr\xF2 chuy\u1EC7n m\u1EDBi",close:"\u0110\xF3ng khung chat",open:"M\u1EDF khung chat",thinking:"\u0110ang suy ngh\u0129\u2026",thoughtFor:t=>`\u0110\xE3 suy ngh\u0129 ${t} gi\xE2y`,reasoning:"Suy lu\u1EADn",toolRunning:"\u0111ang ch\u1EA1y",toolDone:"xong",toolError:"l\u1ED7i",args:"Tham s\u1ED1",result:"K\u1EBFt qu\u1EA3",online:"\u0110ang tr\u1EF1c tuy\u1EBFn",poweredBy:"V\u1EADn h\xE0nh b\u1EDFi",errorGeneric:"C\xF3 l\u1ED7i x\u1EA3y ra. B\u1EA1n th\u1EED l\u1EA1i gi\xFAp m\xECnh nh\xE9.",stopped:"\u0110\xE3 d\u1EEBng.",actionStatus:{pending:"ch\u1EDD","awaiting-confirmation":"c\u1EA7n x\xE1c nh\u1EADn",running:"\u0111ang ch\u1EA1y",done:"xong",denied:"\u0111\xE3 t\u1EEB ch\u1ED1i",error:"l\u1ED7i"},confirmTitle:"Cho ph\xE9p thao t\xE1c n\xE0y?",confirmDestructive:"Thao t\xE1c n\xE0y kh\xF4ng th\u1EC3 ho\xE0n t\xE1c.",allow:"Cho ph\xE9p",deny:"T\u1EEB ch\u1ED1i",actionLimit:t=>`\u0110\xE3 d\u1EEBng sau ${t} l\u01B0\u1EE3t thao t\xE1c t\u1EF1 \u0111\u1ED9ng. G\u1EEDi tin nh\u1EAFn \u0111\u1EC3 ti\u1EBFp t\u1EE5c.`,identityErrors:{IDENTITY_REQUIRED:"B\u1EA1n \u0111\u0103ng nh\u1EADp \u0111\u1EC3 tr\xF2 chuy\u1EC7n nh\xE9.",IDENTITY_LINK_REQUIRED:"B\u1EA1n c\u1EA7n li\xEAn k\u1EBFt t\xE0i kho\u1EA3n chat \u0111\u1EC3 ti\u1EBFp t\u1EE5c.",IDENTITY_CONFLICT:"T\xE0i kho\u1EA3n chat n\xE0y \u0111\xE3 li\xEAn k\u1EBFt v\u1EDBi ng\u01B0\u1EDDi d\xF9ng kh\xE1c. H\xE3y h\u1EE7y li\xEAn k\u1EBFt \u1EDF \u0111\xF3 tr\u01B0\u1EDBc.",LINK_EXPIRED:"Phi\xEAn \u0111\u0103ng nh\u1EADp \u0111\xE3 h\u1EBFt h\u1EA1n. B\u1EA1n g\u1EEDi l\u1EA1i tin nh\u1EAFn gi\xFAp m\xECnh nh\xE9.",LINK_REVOKED:"Quy\u1EC1n truy c\u1EADp c\u1EE7a b\u1EA1n \u0111\xE3 k\u1EBFt th\xFAc. H\xE3y \u0111\u0103ng nh\u1EADp l\u1EA1i \u0111\u1EC3 ti\u1EBFp t\u1EE5c.",PERMISSION_DENIED:"B\u1EA1n kh\xF4ng c\xF3 quy\u1EC1n th\u1EF1c hi\u1EC7n vi\u1EC7c n\xE0y.",SOURCE_UNAVAILABLE:"Hi\u1EC7n ch\u01B0a ki\u1EC3m tra \u0111\u01B0\u1EE3c \u0111\u0103ng nh\u1EADp c\u1EE7a b\u1EA1n. B\u1EA1n th\u1EED l\u1EA1i sau \xEDt ph\xFAt nh\xE9."},admissionErrors:{POLICY_DENIED:"Kh\xF4ng g\u1EEDi \u0111\u01B0\u1EE3c tin nh\u1EAFn n\xE0y. B\u1EA1n th\u1EED r\xFAt g\u1ECDn ho\u1EB7c di\u1EC5n \u0111\u1EA1t l\u1EA1i nh\xE9.",RATE_LIMITED:"B\u1EA1n \u0111ang g\u1EEDi tin nh\u1EAFn h\u01A1i nhanh.",CHALLENGE_REQUIRED:"C\u1EA7n x\xE1c minh th\xEAm. B\u1EA1n th\u1EED l\u1EA1i sau nh\xE9."},cooldown:t=>`B\u1EA1n c\xF3 th\u1EC3 g\u1EEDi l\u1EA1i sau ${t} gi\xE2y`,cooldownStart:t=>`T\u1EA1m d\u1EEBng g\u1EEDi tin nh\u1EAFn. B\u1EA1n c\xF3 th\u1EC3 g\u1EEDi l\u1EA1i sau ${t} gi\xE2y.`,cooldownOver:"B\u1EA1n c\xF3 th\u1EC3 g\u1EEDi tin nh\u1EAFn ti\u1EBFp r\u1ED3i.",linkErrors:{idempotency_key_reused:"Y\xEAu c\u1EA7u li\xEAn k\u1EBFt n\xE0y \u0111\xE3 \u0111\u01B0\u1EE3c d\xF9ng. B\u1EA1n th\u1EED l\u1EA1i nh\xE9.",link_in_progress:"\u0110ang c\xF3 m\u1ED9t li\xEAn k\u1EBFt ch\u01B0a ho\xE0n t\u1EA5t. H\xE3y d\xF9ng m\xE3 \u0111\xE3 nh\u1EADn ho\u1EB7c ch\u1EDD m\xE3 h\u1EBFt h\u1EA1n.",linking_unavailable:"Hi\u1EC7n ch\u01B0a th\u1EC3 li\xEAn k\u1EBFt. B\u1EA1n th\u1EED l\u1EA1i sau nh\xE9."},linkIntro:"G\u1EEDi m\xE3 n\xE0y trong tin nh\u1EAFn ri\xEAng t\u1EEB t\xE0i kho\u1EA3n chat b\u1EA1n mu\u1ED1n li\xEAn k\u1EBFt:",linkContinueOn:t=>`Ti\u1EBFp t\u1EE5c tr\xEAn ${t}`,linkExpires:t=>`M\xE3 h\u1EBFt h\u1EA1n sau ${t} ph\xFAt.`,linkNoTargets:"Ch\u01B0a c\xF3 \u1EE9ng d\u1EE5ng chat n\xE0o \u0111\u01B0\u1EE3c thi\u1EBFt l\u1EADp \u0111\u1EC3 li\xEAn k\u1EBFt.",jobAccess:"Quy\u1EC1n c\xF4ng vi\u1EC7c",jobAccessOpened:"\u0110\xE3 m\u1EDF c\u1EEDa s\u1ED5 quy\u1EC1n c\xF4ng vi\u1EC7c. H\xE3y xem l\u1EA1i v\xE0 x\xE1c nh\u1EADn quy\u1EC1n t\u1EA1i \u0111\xF3.",jobAccessUnavailable:"Ch\u01B0a m\u1EDF \u0111\u01B0\u1EE3c quy\u1EC1n c\xF4ng vi\u1EC7c. H\xE3y \u0111\u0103ng nh\u1EADp l\u1EA1i ho\u1EB7c th\u1EED l\u1EA1i.",jobAccessPopupBlocked:"Cho ph\xE9p c\u1EEDa s\u1ED5 b\u1EADt l\xEAn cho trang n\xE0y r\u1ED3i ch\u1ECDn Quy\u1EC1n c\xF4ng vi\u1EC7c l\u1EA7n n\u1EEFa.",jobAccessPopupClosed:"C\u1EEDa s\u1ED5 \u0111\xE3 \u0111\xF3ng. Ch\u1ECDn Quy\u1EC1n c\xF4ng vi\u1EC7c l\u1EA7n n\u1EEFa \u0111\u1EC3 th\u1EED l\u1EA1i."};function ce(t){return(t||(typeof document<"u"?document.documentElement.lang:"")||(typeof navigator<"u"?navigator.language:"")||"en").toLowerCase().startsWith("vi")?ht:pt}var C={jobAccess:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 3 8 4v5c0 5-8 9-8 9s-8-4-8-9V7l8-4Z"/><path d="m8 12 3 3 5-6"/></svg>',action:'<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/></svg>',chat:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12a8.5 8.5 0 0 1-12.4 7.6L3 21l1.4-5.1A8.5 8.5 0 1 1 21 12Z"/><path d="M8.5 11h.01M12 11h.01M15.5 11h.01"/></svg>',close:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg>',down:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>',newChat:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20h9"/><path d="M16.4 3.6a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4Z"/></svg>',send:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>',stop:'<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><rect x="6" y="6" width="12" height="12" rx="2.5"/></svg>',brain:'<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24A2.5 2.5 0 0 1 9.5 2Z"/><path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24A2.5 2.5 0 0 0 14.5 2Z"/></svg>',tool:'<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76Z"/></svg>'};function y(t,s,e){let n=t.createElement(s);return e&&(n.className=e),n}function gt(t){let s=t.trim();return/^(https?:|mailto:|tel:)/i.test(s)||/^[/#?]/.test(s)&&!s.startsWith("//")?s:null}var ft=/(`+)([\s\S]*?[^`])\1(?!`)|\*\*([^*]+?)\*\*|__([^_]+?)__|~~([^~]+?)~~|\*([^*\s][^*]*?)\*|(?<![\w])_([^_\s][^_]*?)_(?![\w])|\[([^\]]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)|(https?:\/\/[^\s<>()]+[^\s<>().,;:!?'"])/;function T(t,s,e){let n=new RegExp(ft.source,"g"),i=0;for(let o;o=n.exec(s);)if(o.index>i&&e.appendChild(t.createTextNode(s.slice(i,o.index))),i=o.index+o[0].length,o[2]!==void 0){let r=y(t,"code");r.textContent=o[2],e.appendChild(r)}else if(o[3]!==void 0||o[4]!==void 0){let r=y(t,"strong");T(t,o[3]??o[4],r),e.appendChild(r)}else if(o[5]!==void 0){let r=y(t,"del");T(t,o[5],r),e.appendChild(r)}else if(o[6]!==void 0||o[7]!==void 0){let r=y(t,"em");T(t,o[6]??o[7],r),e.appendChild(r)}else if(o[8]!==void 0){let r=gt(o[9]);if(r){let a=y(t,"a");a.href=r,a.target="_blank",a.rel="noopener noreferrer nofollow",T(t,o[8],a),e.appendChild(a)}else e.appendChild(t.createTextNode(o[8]))}else if(o[10]!==void 0){let r=y(t,"a");r.href=o[10],r.target="_blank",r.rel="noopener noreferrer nofollow",r.textContent=o[10],e.appendChild(r)}i<s.length&&e.appendChild(t.createTextNode(s.slice(i)))}var Ne=t=>/^\s*\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)*\|?\s*$/.test(t),He=t=>t.trim().replace(/^\||\|$/g,"").split("|").map(s=>s.trim());function M(t,s){let e=t.createDocumentFragment(),n=s.replace(/\r\n?/g,`
34
+ </div>`;let d=m=>a.querySelector(m);d("h3").textContent=s.confirmTitle,d("code").textContent=e.name;let l=d(".sens");if(l.textContent=e.sensitivity,l.dataset.level=e.sensitivity,d(".confirm-text").textContent=e.description,e.sensitivity==="destructive"){let m=d(".confirm-warn");m.hidden=!1,m.textContent=s.confirmDestructive}let p=JSON.stringify(n,null,2),g=d(".confirm-args");p&&p!=="{}"?g.textContent=p:g.remove();let h=d(".deny"),u=d(".allow");return h.textContent=s.deny,u.textContent=s.allow,e.sensitivity==="destructive"&&u.classList.add("danger"),new Promise(m=>{let b=!1,x=y=>{b||(b=!0,i?.removeEventListener("abort",w),a.remove(),c?.focus?.(),m(y))},w=()=>x(!1);if(i?.aborted)return x(!1);i?.addEventListener("abort",w,{once:!0}),h.addEventListener("click",()=>x(!1)),u.addEventListener("click",()=>x(!0)),a.addEventListener("keydown",y=>{y.key==="Escape"?(y.preventDefault(),y.stopPropagation(),x(!1)):y.key==="Tab"&&(y.preventDefault(),(o.activeElement===h?u:h).focus())}),t.appendChild(a),h.focus()})}var At={title:"Assistant",greeting:"Hi there \u{1F44B}",greetingBody:"Ask me anything. I can look things up and use tools to help you.",placeholder:"Type a message\u2026",send:"Send",stop:"Stop",newChat:"New conversation",close:"Close chat",open:"Open chat",thinking:"Thinking\u2026",thoughtFor:t=>`Thought for ${t}s`,reasoning:"Reasoning",toolRunning:"running",toolDone:"done",toolError:"error",args:"Arguments",result:"Result",online:"Online",poweredBy:"Powered by",errorGeneric:"Something went wrong. Please try again.",stopped:"Stopped.",actionStatus:{pending:"queued","awaiting-confirmation":"needs approval",running:"running",done:"done",denied:"declined",error:"failed"},confirmTitle:"Allow this action?",confirmDestructive:"This can't be undone.",allow:"Allow",deny:"Deny",actionLimit:t=>`Stopped after ${t} automatic action rounds. Send a message to continue.`,identityErrors:{IDENTITY_REQUIRED:"Please sign in to chat.",IDENTITY_LINK_REQUIRED:"Link your chat account to continue.",IDENTITY_CONFLICT:"This chat account is already linked to another user. Unlink it there first.",LINK_EXPIRED:"Your session expired. Send your message again.",LINK_REVOKED:"Your access has ended. Sign in again to continue.",PERMISSION_DENIED:"You don't have access to this.",SOURCE_UNAVAILABLE:"We couldn't check your sign-in right now. Please try again shortly."},admissionErrors:{POLICY_DENIED:"This message can't be sent. Try shortening or rephrasing it.",RATE_LIMITED:"You're sending messages too quickly.",CHALLENGE_REQUIRED:"Extra verification is needed. Please try again later."},cooldown:t=>`You can send again in ${t}s`,cooldownStart:t=>`Sending is paused. You can send again in ${t} second${t===1?"":"s"}.`,cooldownOver:"You can send messages again.",linkErrors:{idempotency_key_reused:"This link request was already used. Please try again.",link_in_progress:"A link is already in progress. Use the code you got, or wait for it to expire.",linking_unavailable:"Linking is not available right now. Please try again later."},linkIntro:"Send this code in a direct message from the chat account you want to link:",linkContinueOn:t=>`Continue on ${t}`,linkExpires:t=>`The code expires in ${t} min.`,linkNoTargets:"No chat app is set up for linking yet.",jobAccess:"Job access",jobAccessOpened:"Job access opened in a new window. Review and confirm any permissions there.",jobAccessUnavailable:"Job access could not be opened. Sign in again or retry.",jobAccessPopupBlocked:"Allow popups for this site, then choose Job access again.",jobAccessPopupClosed:"The window was closed. Choose Job access again to retry.",pageShare:"Share this page with the assistant for this message",pageChanged:"The page changed. Review it and choose to share again before sending.",pageUnavailable:"Page details are unavailable. You can send without them."},Ct={title:"Tr\u1EE3 l\xFD",greeting:"Xin ch\xE0o \u{1F44B}",greetingBody:"B\u1EA1n c\u1EA7n h\u1ECFi g\xEC c\u1EE9 nh\u1EAFn nh\xE9. M\xECnh c\xF3 th\u1EC3 tra c\u1EE9u v\xE0 d\xF9ng c\xF4ng c\u1EE5 \u0111\u1EC3 h\u1ED7 tr\u1EE3 b\u1EA1n.",placeholder:"Nh\u1EADp tin nh\u1EAFn\u2026",send:"G\u1EEDi",stop:"D\u1EEBng",newChat:"Cu\u1ED9c tr\xF2 chuy\u1EC7n m\u1EDBi",close:"\u0110\xF3ng khung chat",open:"M\u1EDF khung chat",thinking:"\u0110ang suy ngh\u0129\u2026",thoughtFor:t=>`\u0110\xE3 suy ngh\u0129 ${t} gi\xE2y`,reasoning:"Suy lu\u1EADn",toolRunning:"\u0111ang ch\u1EA1y",toolDone:"xong",toolError:"l\u1ED7i",args:"Tham s\u1ED1",result:"K\u1EBFt qu\u1EA3",online:"\u0110ang tr\u1EF1c tuy\u1EBFn",poweredBy:"V\u1EADn h\xE0nh b\u1EDFi",errorGeneric:"C\xF3 l\u1ED7i x\u1EA3y ra. B\u1EA1n th\u1EED l\u1EA1i gi\xFAp m\xECnh nh\xE9.",stopped:"\u0110\xE3 d\u1EEBng.",actionStatus:{pending:"ch\u1EDD","awaiting-confirmation":"c\u1EA7n x\xE1c nh\u1EADn",running:"\u0111ang ch\u1EA1y",done:"xong",denied:"\u0111\xE3 t\u1EEB ch\u1ED1i",error:"l\u1ED7i"},confirmTitle:"Cho ph\xE9p thao t\xE1c n\xE0y?",confirmDestructive:"Thao t\xE1c n\xE0y kh\xF4ng th\u1EC3 ho\xE0n t\xE1c.",allow:"Cho ph\xE9p",deny:"T\u1EEB ch\u1ED1i",actionLimit:t=>`\u0110\xE3 d\u1EEBng sau ${t} l\u01B0\u1EE3t thao t\xE1c t\u1EF1 \u0111\u1ED9ng. G\u1EEDi tin nh\u1EAFn \u0111\u1EC3 ti\u1EBFp t\u1EE5c.`,identityErrors:{IDENTITY_REQUIRED:"B\u1EA1n \u0111\u0103ng nh\u1EADp \u0111\u1EC3 tr\xF2 chuy\u1EC7n nh\xE9.",IDENTITY_LINK_REQUIRED:"B\u1EA1n c\u1EA7n li\xEAn k\u1EBFt t\xE0i kho\u1EA3n chat \u0111\u1EC3 ti\u1EBFp t\u1EE5c.",IDENTITY_CONFLICT:"T\xE0i kho\u1EA3n chat n\xE0y \u0111\xE3 li\xEAn k\u1EBFt v\u1EDBi ng\u01B0\u1EDDi d\xF9ng kh\xE1c. H\xE3y h\u1EE7y li\xEAn k\u1EBFt \u1EDF \u0111\xF3 tr\u01B0\u1EDBc.",LINK_EXPIRED:"Phi\xEAn \u0111\u0103ng nh\u1EADp \u0111\xE3 h\u1EBFt h\u1EA1n. B\u1EA1n g\u1EEDi l\u1EA1i tin nh\u1EAFn gi\xFAp m\xECnh nh\xE9.",LINK_REVOKED:"Quy\u1EC1n truy c\u1EADp c\u1EE7a b\u1EA1n \u0111\xE3 k\u1EBFt th\xFAc. H\xE3y \u0111\u0103ng nh\u1EADp l\u1EA1i \u0111\u1EC3 ti\u1EBFp t\u1EE5c.",PERMISSION_DENIED:"B\u1EA1n kh\xF4ng c\xF3 quy\u1EC1n th\u1EF1c hi\u1EC7n vi\u1EC7c n\xE0y.",SOURCE_UNAVAILABLE:"Hi\u1EC7n ch\u01B0a ki\u1EC3m tra \u0111\u01B0\u1EE3c \u0111\u0103ng nh\u1EADp c\u1EE7a b\u1EA1n. B\u1EA1n th\u1EED l\u1EA1i sau \xEDt ph\xFAt nh\xE9."},admissionErrors:{POLICY_DENIED:"Kh\xF4ng g\u1EEDi \u0111\u01B0\u1EE3c tin nh\u1EAFn n\xE0y. B\u1EA1n th\u1EED r\xFAt g\u1ECDn ho\u1EB7c di\u1EC5n \u0111\u1EA1t l\u1EA1i nh\xE9.",RATE_LIMITED:"B\u1EA1n \u0111ang g\u1EEDi tin nh\u1EAFn h\u01A1i nhanh.",CHALLENGE_REQUIRED:"C\u1EA7n x\xE1c minh th\xEAm. B\u1EA1n th\u1EED l\u1EA1i sau nh\xE9."},cooldown:t=>`B\u1EA1n c\xF3 th\u1EC3 g\u1EEDi l\u1EA1i sau ${t} gi\xE2y`,cooldownStart:t=>`T\u1EA1m d\u1EEBng g\u1EEDi tin nh\u1EAFn. B\u1EA1n c\xF3 th\u1EC3 g\u1EEDi l\u1EA1i sau ${t} gi\xE2y.`,cooldownOver:"B\u1EA1n c\xF3 th\u1EC3 g\u1EEDi tin nh\u1EAFn ti\u1EBFp r\u1ED3i.",linkErrors:{idempotency_key_reused:"Y\xEAu c\u1EA7u li\xEAn k\u1EBFt n\xE0y \u0111\xE3 \u0111\u01B0\u1EE3c d\xF9ng. B\u1EA1n th\u1EED l\u1EA1i nh\xE9.",link_in_progress:"\u0110ang c\xF3 m\u1ED9t li\xEAn k\u1EBFt ch\u01B0a ho\xE0n t\u1EA5t. H\xE3y d\xF9ng m\xE3 \u0111\xE3 nh\u1EADn ho\u1EB7c ch\u1EDD m\xE3 h\u1EBFt h\u1EA1n.",linking_unavailable:"Hi\u1EC7n ch\u01B0a th\u1EC3 li\xEAn k\u1EBFt. B\u1EA1n th\u1EED l\u1EA1i sau nh\xE9."},linkIntro:"G\u1EEDi m\xE3 n\xE0y trong tin nh\u1EAFn ri\xEAng t\u1EEB t\xE0i kho\u1EA3n chat b\u1EA1n mu\u1ED1n li\xEAn k\u1EBFt:",linkContinueOn:t=>`Ti\u1EBFp t\u1EE5c tr\xEAn ${t}`,linkExpires:t=>`M\xE3 h\u1EBFt h\u1EA1n sau ${t} ph\xFAt.`,linkNoTargets:"Ch\u01B0a c\xF3 \u1EE9ng d\u1EE5ng chat n\xE0o \u0111\u01B0\u1EE3c thi\u1EBFt l\u1EADp \u0111\u1EC3 li\xEAn k\u1EBFt.",jobAccess:"Quy\u1EC1n c\xF4ng vi\u1EC7c",jobAccessOpened:"\u0110\xE3 m\u1EDF c\u1EEDa s\u1ED5 quy\u1EC1n c\xF4ng vi\u1EC7c. H\xE3y xem l\u1EA1i v\xE0 x\xE1c nh\u1EADn quy\u1EC1n t\u1EA1i \u0111\xF3.",jobAccessUnavailable:"Ch\u01B0a m\u1EDF \u0111\u01B0\u1EE3c quy\u1EC1n c\xF4ng vi\u1EC7c. H\xE3y \u0111\u0103ng nh\u1EADp l\u1EA1i ho\u1EB7c th\u1EED l\u1EA1i.",jobAccessPopupBlocked:"Cho ph\xE9p c\u1EEDa s\u1ED5 b\u1EADt l\xEAn cho trang n\xE0y r\u1ED3i ch\u1ECDn Quy\u1EC1n c\xF4ng vi\u1EC7c l\u1EA7n n\u1EEFa.",jobAccessPopupClosed:"C\u1EEDa s\u1ED5 \u0111\xE3 \u0111\xF3ng. Ch\u1ECDn Quy\u1EC1n c\xF4ng vi\u1EC7c l\u1EA7n n\u1EEFa \u0111\u1EC3 th\u1EED l\u1EA1i.",pageShare:"Chia s\u1EBB trang n\xE0y v\u1EDBi tr\u1EE3 l\xFD trong tin nh\u1EAFn n\xE0y",pageChanged:"Trang \u0111\xE3 thay \u0111\u1ED5i. H\xE3y xem l\u1EA1i v\xE0 ch\u1ECDn chia s\u1EBB tr\u01B0\u1EDBc khi g\u1EEDi.",pageUnavailable:"Kh\xF4ng th\u1EC3 \u0111\u1ECDc n\u1ED9i dung trang. B\u1EA1n v\u1EABn c\xF3 th\u1EC3 g\u1EEDi tin nh\u1EAFn."};function ue(t){return(t||(typeof document<"u"?document.documentElement.lang:"")||(typeof navigator<"u"?navigator.language:"")||"en").toLowerCase().startsWith("vi")?Ct:At}var C={jobAccess:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m12 3 8 4v5c0 5-8 9-8 9s-8-4-8-9V7l8-4Z"/><path d="m8 12 3 3 5-6"/></svg>',action:'<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M13 2 4 14h7l-1 8 9-12h-7l1-8Z"/></svg>',chat:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M21 12a8.5 8.5 0 0 1-12.4 7.6L3 21l1.4-5.1A8.5 8.5 0 1 1 21 12Z"/><path d="M8.5 11h.01M12 11h.01M15.5 11h.01"/></svg>',close:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M18 6 6 18M6 6l12 12"/></svg>',down:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.4" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m6 9 6 6 6-6"/></svg>',newChat:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 20h9"/><path d="M16.4 3.6a2.1 2.1 0 1 1 3 3L7 19l-4 1 1-4Z"/></svg>',send:'<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 19V5M5 12l7-7 7 7"/></svg>',stop:'<svg viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><rect x="6" y="6" width="12" height="12" rx="2.5"/></svg>',brain:'<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M9.5 2A2.5 2.5 0 0 1 12 4.5v15a2.5 2.5 0 0 1-4.96.44 2.5 2.5 0 0 1-2.96-3.08 3 3 0 0 1-.34-5.58 2.5 2.5 0 0 1 1.32-4.24A2.5 2.5 0 0 1 9.5 2Z"/><path d="M14.5 2A2.5 2.5 0 0 0 12 4.5v15a2.5 2.5 0 0 0 4.96.44 2.5 2.5 0 0 0 2.96-3.08 3 3 0 0 0 .34-5.58 2.5 2.5 0 0 0-1.32-4.24A2.5 2.5 0 0 0 14.5 2Z"/></svg>',tool:'<svg class="ic" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76Z"/></svg>'};var q=new WeakMap,H=new WeakMap;function U(t){for(let s of t.querySelectorAll("img.md-image"))q.get(s)?.disconnect(),q.delete(s),H.get(s)?.abort(),H.delete(s)}function St(t,s,e){try{if(!s||/[\u0000-\u0020\u007f\\]/.test(s)||s.startsWith("//"))return null;let n=decodeURIComponent(s);if(/[\u0000-\u0020\u007f\\]/.test(n)||n.startsWith("//"))return null;let i=new URL(t.defaultView?.location.href??t.baseURI),r=new URL(s,t.baseURI);return r.username||r.password||!["http:","https:"].includes(r.protocol)||/\.svg$/i.test(decodeURIComponent(r.pathname))?null:r.origin===i.origin?r.href:r.protocol!=="https:"?null:e.some(c=>{try{let a=new URL(c);return a.protocol==="https:"&&!a.username&&!a.password&&a.href===a.origin+"/"&&a.origin===r.origin}catch{return!1}})?r.href:null}catch{return null}}function v(t,s,e){let n=t.createElement(s);return e&&(n.className=e),n}function Tt(t){let s=t.trim();return/^(https?:|mailto:|tel:)/i.test(s)||/^[/#?]/.test(s)&&!s.startsWith("//")?s:null}var It=/\\!\[[^\]]*\]\([^)\s]+\)|(`+)([\s\S]*?[^`])\1(?!`)|\*\*([^*]+?)\*\*|__([^_]+?)__|~~([^~]+?)~~|\*([^*\s][^*]*?)\*|(?<![\w])_([^_\s][^_]*?)_(?![\w])|(?<!\\)!\[([^\]]*)\]\(([^)\s]+)\)|\[([^\]]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)|(https?:\/\/[^\s<>()]+[^\s<>().,;:!?'"])/;function T(t,s,e,n={}){let i=new RegExp(It.source,"g"),r=0;for(let o;o=i.exec(s);)if(o.index>r&&e.appendChild(t.createTextNode(s.slice(r,o.index))),r=o.index+o[0].length,o[0].startsWith("\\!"))e.appendChild(t.createTextNode(o[0].slice(1)));else if(o[2]!==void 0){let c=v(t,"code");c.textContent=o[2],e.appendChild(c)}else if(o[3]!==void 0||o[4]!==void 0){let c=v(t,"strong");T(t,o[3]??o[4],c,n),e.appendChild(c)}else if(o[5]!==void 0){let c=v(t,"del");T(t,o[5],c,n),e.appendChild(c)}else if(o[6]!==void 0||o[7]!==void 0){let c=v(t,"em");T(t,o[6]??o[7],c,n),e.appendChild(c)}else if(o[8]!==void 0){let c=n.deferImages?null:St(t,o[9],n.imageOrigins??[]);if(!c||!n.imageProxy)e.appendChild(t.createTextNode(o[8]));else{let a=v(t,"img","md-image");a.alt=o[8],a.setAttribute("loading","lazy"),a.setAttribute("decoding","async"),a.referrerPolicy="no-referrer";let d=!1,l=()=>{let g=new AbortController;return H.set(a,g),n.imageProxy(c,g.signal).then(h=>{!g.signal.aborted&&a.isConnected&&(a.src=h)}).catch(()=>{!g.signal.aborted&&a.isConnected&&a.replaceWith(t.createTextNode(a.alt))}).finally(()=>{H.get(a)===g&&H.delete(a)})};a.addEventListener("error",()=>{d?a.replaceWith(t.createTextNode(a.alt)):(d=!0,l())}),e.appendChild(a);let p=t.defaultView?.IntersectionObserver;if(p){let g=new p(h=>{h.some(u=>u.isIntersecting)&&(g.disconnect(),q.delete(a),a.parentNode&&l())},{rootMargin:"200px"});q.set(a,g),g.observe(a)}else l()}}else if(o[10]!==void 0){let c=Tt(o[11]);if(c){let a=v(t,"a");a.href=c,a.target="_blank",a.rel="noopener noreferrer nofollow",T(t,o[10],a,n),e.appendChild(a)}else e.appendChild(t.createTextNode(o[10]))}else if(o[12]!==void 0){let c=v(t,"a");c.href=o[12],c.target="_blank",c.rel="noopener noreferrer nofollow",c.textContent=o[12],e.appendChild(c)}r<s.length&&e.appendChild(t.createTextNode(s.slice(r)))}var Be=t=>/^\s*\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)*\|?\s*$/.test(t),ze=t=>t.trim().replace(/^\||\|$/g,"").split("|").map(s=>s.trim());function R(t,s,e={}){let n=t.createDocumentFragment(),i=s.replace(/\r\n?/g,`
35
35
  `).split(`
36
- `),i=0;for(;i<n.length;){let o=n[i];if(!o.trim()){i++;continue}let r=o.match(/^\s*(```+|~~~+)\s*([\w+-]*)/);if(r){let u=[];for(i++;i<n.length&&!n[i].trim().startsWith(r[1]);)u.push(n[i++]);i++;let f=y(t,"pre"),p=y(t,"code");r[2]&&(p.dataset.lang=r[2]),p.textContent=u.join(`
37
- `),f.appendChild(p),e.appendChild(f);continue}let a=o.match(/^(#{1,6})\s+(.*)$/);if(a){let u=`h${Math.min(6,a[1].length+2)}`,f=y(t,u);T(t,a[2],f),e.appendChild(f),i++;continue}if(/^\s*([-*_])(\s*\1){2,}\s*$/.test(o)){e.appendChild(y(t,"hr")),i++;continue}if(o.includes("|")&&i+1<n.length&&Ne(n[i+1])){let u=y(t,"div","table"),f=y(t,"table"),p=y(t,"thead"),h=y(t,"tr");for(let b of He(o)){let v=y(t,"th");T(t,b,v),h.appendChild(v)}p.appendChild(h),f.appendChild(p);let m=y(t,"tbody");for(i+=2;i<n.length&&n[i].includes("|")&&n[i].trim();){let b=y(t,"tr");for(let v of He(n[i])){let w=y(t,"td");T(t,v,w),b.appendChild(w)}m.appendChild(b),i++}f.appendChild(m),u.appendChild(f),e.appendChild(u);continue}if(/^\s*>/.test(o)){let u=[];for(;i<n.length&&/^\s*>/.test(n[i]);)u.push(n[i++].replace(/^\s*>\s?/,""));let f=y(t,"blockquote");f.appendChild(M(t,u.join(`
38
- `))),e.appendChild(f);continue}let d=o.match(/^(\s*)([-*+]|\d+[.)])\s+(.*)$/);if(d){let u=/\d/.test(d[2]),f=y(t,u?"ol":"ul");u&&parseInt(d[2],10)!==1&&f.setAttribute("start",String(parseInt(d[2],10)));let p=d[1].length;for(;i<n.length;){let h=n[i].match(/^(\s*)([-*+]|\d+[.)])\s+(.*)$/);if(!h||h[1].length<p||/\d/.test(h[2])!==u)break;if(h[1].length>p){let b=[];for(;i<n.length&&/^\s+/.test(n[i])&&n[i].match(/^(\s*)/)[1].length>p;)b.push(n[i++].slice(p+2));f.lastElementChild?.appendChild(M(t,b.join(`
39
- `)));continue}let m=y(t,"li");T(t,h[3],m),f.appendChild(m),i++}e.appendChild(f);continue}let l=[];for(;i<n.length&&n[i].trim()&&!/^\s*(```|~~~|#{1,6}\s|>|([-*+]|\d+[.)])\s)/.test(n[i])&&!(n[i].includes("|")&&i+1<n.length&&Ne(n[i+1]));)l.push(n[i++]);l.length||l.push(n[i++]);let c=y(t,"p");l.forEach((u,f)=>{f&&c.appendChild(y(t,"br")),T(t,u,c)}),e.appendChild(c)}return e}var j=class{constructor(s,e){g(this,"onTick",s);g(this,"onEnd",e);g(this,"until",0);g(this,"tick");g(this,"done")}get active(){return Date.now()<this.until}get secondsLeft(){return Math.max(0,Math.ceil((this.until-Date.now())/1e3))}start(s){let e=Date.now()+Math.max(0,s);e<=this.until||(this.until=e,this.clear(),this.tick=setInterval(()=>this.onTick(this.secondsLeft),1e3),this.done=setTimeout(()=>{this.until=0,this.clear(),this.onEnd()},e-Date.now()))}clear(){clearInterval(this.tick),clearTimeout(this.done)}};var De=`
36
+ `),r=0;for(;r<i.length;){let o=i[r];if(!o.trim()){r++;continue}let c=o.match(/^\s*(```+|~~~+)\s*([\w+-]*)/);if(c){let g=[];for(r++;r<i.length&&!i[r].trim().startsWith(c[1]);)g.push(i[r++]);r++;let h=v(t,"pre"),u=v(t,"code");c[2]&&(u.dataset.lang=c[2]),u.textContent=g.join(`
37
+ `),h.appendChild(u),n.appendChild(h);continue}let a=o.match(/^(#{1,6})\s+(.*)$/);if(a){let g=`h${Math.min(6,a[1].length+2)}`,h=v(t,g);T(t,a[2],h,e),n.appendChild(h),r++;continue}if(/^\s*([-*_])(\s*\1){2,}\s*$/.test(o)){n.appendChild(v(t,"hr")),r++;continue}if(o.includes("|")&&r+1<i.length&&Be(i[r+1])){let g=v(t,"div","table"),h=v(t,"table"),u=v(t,"thead"),m=v(t,"tr");for(let x of ze(o)){let w=v(t,"th");T(t,x,w,e),m.appendChild(w)}u.appendChild(m),h.appendChild(u);let b=v(t,"tbody");for(r+=2;r<i.length&&i[r].includes("|")&&i[r].trim();){let x=v(t,"tr");for(let w of ze(i[r])){let y=v(t,"td");T(t,w,y,e),x.appendChild(y)}b.appendChild(x),r++}h.appendChild(b),g.appendChild(h),n.appendChild(g);continue}if(/^\s*>/.test(o)){let g=[];for(;r<i.length&&/^\s*>/.test(i[r]);)g.push(i[r++].replace(/^\s*>\s?/,""));let h=v(t,"blockquote");h.appendChild(R(t,g.join(`
38
+ `),e)),n.appendChild(h);continue}let d=o.match(/^(\s*)([-*+]|\d+[.)])\s+(.*)$/);if(d){let g=/\d/.test(d[2]),h=v(t,g?"ol":"ul");g&&parseInt(d[2],10)!==1&&h.setAttribute("start",String(parseInt(d[2],10)));let u=d[1].length;for(;r<i.length;){let m=i[r].match(/^(\s*)([-*+]|\d+[.)])\s+(.*)$/);if(!m||m[1].length<u||/\d/.test(m[2])!==g)break;if(m[1].length>u){let x=[];for(;r<i.length&&/^\s+/.test(i[r])&&i[r].match(/^(\s*)/)[1].length>u;)x.push(i[r++].slice(u+2));h.lastElementChild?.appendChild(R(t,x.join(`
39
+ `),e));continue}let b=v(t,"li");T(t,m[3],b,e),h.appendChild(b),r++}n.appendChild(h);continue}let l=[];for(;r<i.length&&i[r].trim()&&!/^\s*(```|~~~|#{1,6}\s|>|([-*+]|\d+[.)])\s)/.test(i[r])&&!(i[r].includes("|")&&r+1<i.length&&Be(i[r+1]));)l.push(i[r++]);l.length||l.push(i[r++]);let p=v(t,"p");l.forEach((g,h)=>{h&&p.appendChild(v(t,"br")),T(t,g,p,e)}),n.appendChild(p)}return n}var J=class{constructor(s,e){f(this,"onTick",s);f(this,"onEnd",e);f(this,"until",0);f(this,"tick");f(this,"done")}get active(){return Date.now()<this.until}get secondsLeft(){return Math.max(0,Math.ceil((this.until-Date.now())/1e3))}start(s){let e=Date.now()+Math.max(0,s);e<=this.until||(this.until=e,this.clear(),this.tick=setInterval(()=>this.onTick(this.secondsLeft),1e3),this.done=setTimeout(()=>{this.until=0,this.clear(),this.onEnd()},e-Date.now()))}clear(){clearInterval(this.tick),clearTimeout(this.done)}};var qe=`
40
40
  :host {
41
41
  --dw-accent: #5446e8;
42
42
  --dw-accent-contrast: #fff;
@@ -184,6 +184,7 @@ button { font: inherit; color: inherit; background: none; border: 0; cursor: poi
184
184
  .md li { margin: 3px 0; }
185
185
  .md h3, .md h4, .md h5, .md h6 { margin: 14px 0 6px; font-size: 15px; line-height: 1.35; }
186
186
  .md a { color: var(--dw-accent); text-decoration: underline; text-underline-offset: 2px; }
187
+ .md .md-image { display: block; max-width: 100%; max-height: 320px; min-height: 48px; width: auto; height: auto; object-fit: contain; border-radius: 8px; }
187
188
  .md code { font-family: var(--dw-mono); font-size: .86em; background: var(--dw-surface); padding: 1.5px 5px; border-radius: 5px; }
188
189
  .md pre { background: #12132a; color: #e6e6f5; padding: 12px 14px; border-radius: 12px; overflow-x: auto; font-size: 12.5px; line-height: 1.55; }
189
190
  .md pre code { background: none; padding: 0; color: inherit; font-size: inherit; }
@@ -278,6 +279,9 @@ details > summary svg.ic { width: 14px; height: 14px; flex: none; }
278
279
 
279
280
  /* ---------- composer ---------- */
280
281
  .composer { padding: 10px 12px 12px; border-top: 1px solid var(--dw-border); background: var(--dw-bg); }
282
+ .page-context { font-size: 12px; margin-bottom: 8px; }
283
+ .page-context label { display: flex; align-items: center; gap: 6px; cursor: pointer; }
284
+ .page-preview { max-height: 96px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere; padding: 6px; margin: 6px 0; border: 1px solid var(--dw-border); border-radius: 6px; font: inherit; }
281
285
  .box {
282
286
  display: flex; align-items: flex-end; gap: 8px; border: 1px solid var(--dw-border); border-radius: 14px;
283
287
  padding: 6px 6px 6px 12px; background: var(--dw-bg); transition: border-color .15s, box-shadow .15s;
@@ -305,8 +309,8 @@ textarea::placeholder { color: var(--dw-muted); }
305
309
  .agent-select { font-size: 16px; max-width: 200px; }
306
310
  }
307
311
  @media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
308
- `;var mt=5e3,Be=["show-reasoning","show-tool-calls","allow-agent-switch","open","persist","hide-branding","launcher-avatar","dom-actions"],Oe=["endpoint","agent","title","subtitle","greeting","intro","placeholder","suggestions","avatar","position","mode","theme","accent-color","locale","gateway-url","gateway-token","width","height","z-index","dom-actions-root",...Be],$e=t=>t.replace(/-([a-z])/g,(s,e)=>e.toUpperCase()),bt=t=>t!==null&&!/^(false|0|off|no)$/i.test(t),je=()=>{let t=crypto.getRandomValues(new Uint8Array(9));return Array.from(t,s=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"[s&63]).join("")},wt=t=>t.replace(/^mcp_[^_]+(?:_[^_]+)*?__/,"").replace(/_/g," "),_={get(t){try{return localStorage.getItem(t)}catch{return null}},set(t,s){try{localStorage.setItem(t,s)}catch{}}},yt=null;function xt(){return yt??(yt=new Promise((t,s)=>{if(window.turnstile)return t();let e=document.createElement("script");e.src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit",e.async=!0,e.onload=()=>t(),e.onerror=()=>s(new Error("Could not load Turnstile")),document.head.appendChild(e)}))}var vt=typeof HTMLElement>"u"?class{}:HTMLElement,H=class extends vt{constructor(){super();g(this,"root");g(this,"overrides",{});g(this,"api",null);g(this,"apiKey","");g(this,"server",null);g(this,"agentId","");g(this,"conversationId","");g(this,"messages",[]);g(this,"running",null);g(this,"jobAccessLaunch",null);g(this,"activated",!1);g(this,"strings",ce());g(this,"mql",null);g(this,"registry",new N);g(this,"propActionNames",new Set);g(this,"hooks",{});g(this,"dom",null);g(this,"acks",new Map);g(this,"cooldown",new j(e=>this.renderCooldown(e),()=>this.endCooldown()));g(this,"els");g(this,"onScheme",()=>this.applyTheme());g(this,"pendingFrame",0);g(this,"following",!0);this.root=this.attachShadow({mode:"open"})}static get observedAttributes(){return Oe}get config(){let e={endpoint:"/api/dewee"};for(let n of Oe){let i=this.getAttribute(n);i!==null&&(Be.includes(n)?e[$e(n)]=bt(i):n==="suggestions"?e.suggestions=i.trim().startsWith("[")?Ct(i,[]):i.split("|").map(o=>o.trim()).filter(Boolean):n==="z-index"?e.zIndex=Number(i):e[$e(n)]=i)}return{...e,...this.overrides,...this.hooks}}configure(e){let{actions:n,confirm:i,getPageContext:o,headers:r,fetch:a,domActionsRoot:d,...l}=e,c=u=>Object.prototype.hasOwnProperty.call(e,u);c("actions")&&this.setPropActions(n??[]),c("confirm")&&(this.hooks.confirm=i),c("getPageContext")&&(this.hooks.getPageContext=o),c("headers")&&(this.hooks.headers=r),c("fetch")&&(this.hooks.fetch=a),c("domActionsRoot")&&(d===void 0?delete this.hooks.domActionsRoot:this.hooks.domActionsRoot=d),Object.keys(l).length&&(this.overrides={...this.overrides,...l},this.els&&this.applyConfig())}registerActions(e){this.registry.register(e)}unregisterAction(e){return this.propActionNames.delete(e),this.registry.unregister(e)}get headers(){return this.hooks.headers}set headers(e){this.hooks.headers=e}get fetch(){return this.hooks.fetch}set fetch(e){this.hooks.fetch=e}get actionNames(){return this.actionRegistry().names()}actionRegistry(){if(!this.config.domActions)return this.registry;this.dom??(this.dom=Ie({root:()=>this.hooks.domActionsRoot??this.getAttribute("dom-actions-root")??void 0,exclude:r=>r===this||this.contains(r)||r.closest("dewee-chat")!==null}));let e=this.registry.names().map(r=>this.registry.get(r)),n=S.maxActions-e.length,i=this.dom.actions.filter(r=>!this.registry.get(r.name)).slice(0,Math.max(0,n)),o=new N;return o.register([...e,...i]),o}setPropActions(e){let n=new Set(e.map(i=>i.name));for(let i of this.propActionNames)n.has(i)||this.registry.unregister(i);e.length&&this.registry.register(e),this.propActionNames=n}open(){this.config.mode!=="inline"&&(this.setAttribute("data-open",""),this.removeAttribute("data-unread"),this.els.launcher.setAttribute("aria-expanded","true"),this.activate(),setTimeout(()=>this.els.input.focus(),120),this.emit("dewee:open"))}close(){this.config.mode!=="inline"&&(this.removeAttribute("data-open"),this.els.launcher.setAttribute("aria-expanded","false"),this.emit("dewee:close"))}toggle(){this.hasAttribute("data-open")?this.close():this.open()}async send(e){let n=e.trim();if(!n||this.running||this.cooldown.active)return;this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),await this.activate(),this.els.input.value="",this.autosize();let i={message:n,hidden:!1};for(let o=0;i;o++){let r=await this.runTurn(i.message,i.hidden);if(i=null,r.status!=="done"||r.stopped||!this.actionRegistry().size)break;let{calls:a}=K(r.content);if(!a.length)break;r.actions=a.map(c=>({id:c.id,name:c.name,args:c.ok?c.args:void 0,status:"pending"}));let d=this.config.maxActionRounds??5;if(o>=d){for(let c of r.actions)Object.assign(c,{status:"error",error:"Automatic action limit reached"});this.updateMessage(r),this.showNotice(this.strings.actionLimit(d));break}this.updateMessage(r);let l=await this.runActions(r,a);l&&(i={message:ve(l,this.server?.maxMessageLength??4e3),hidden:!0})}}async runTurn(e,n){this.pushMessage({role:"user",content:e,hidden:n});let i={role:"assistant",content:"",status:"streaming",startedAt:Date.now()};this.pushMessage(i),this.setRunning(new AbortController),this.emit("dewee:send",{message:e,agent:this.agentId,conversationId:this.conversationId,auto:n||void 0});try{await this.client().ensureSession(),await this.client().chat(this.chatBody(e),o=>this.onStreamEvent(i,o),this.running.signal),i.status==="streaming"&&(i.status="done")}catch(o){o.name==="AbortError"?(i.status="done",i.stopped=!0,i.content||(i.content=`_${this.strings.stopped}_`)):(i.status="error",this.showError(i,o))}finally{this.finishThinking(i),this.updateMessage(i),this.setRunning(null),i.status==="done"&&(i.actionsHash&&i.ackVisitor&&!i.stopped&&this.setAck(i.actionsHash,i.ackVisitor),this.emit("dewee:reply",{content:i.content,agent:this.agentId,conversationId:this.conversationId}),this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.setAttribute("data-unread",""))}return i}chatBody(e){let n={message:e,agent:this.agentId,conversationId:this.conversationId},i=this.actionRegistry();if(i.size){n.actions=i.manifest();let r=this.client().visitorId(),a=r?this.getAck(r):void 0;a&&(n.actionsHash=a)}let o=this.pageContext();return o!==void 0&&(n.pageContext=o),n}pageContext(){let e=this.hooks.getPageContext;if(e)try{let n=e();if(n==null)return;let i=new TextEncoder().encode(JSON.stringify(n)).length;return i<=S.maxPageContextBytes?n:(console.warn(`[dewee-webchat] getPageContext() returned ${i} bytes; the limit is ${S.maxPageContextBytes}. Context not sent.`),{truncated:!0})}catch(n){console.warn("[dewee-webchat] getPageContext() failed:",n);return}}ackKey(e){return`dewee-webchat:actions:${this.config.endpoint}:${this.agentId}:${e}:${this.conversationId}`}getAck(e){let n=this.ackKey(e);return this.acks.get(n)??(this.config.persist!==!1?_.get(n)??void 0:void 0)}setAck(e,n){let i=this.ackKey(n);this.acks.set(i,e),this.config.persist!==!1&&_.set(i,e)}async runActions(e,n){let i=new AbortController;this.setRunning(i);let o=[],r={agent:this.agentId,conversationId:this.conversationId},a=this.actionRegistry();try{for(let[d,l]of n.entries()){let c=e.actions[d],u=l.ok?a.get(l.name)?.sensitivity:void 0,f=l.ok?l.args:void 0;this.emit("dewee:action",{phase:"start",id:l.id,name:l.name,sensitivity:u,args:f,...r});let p=await Se(l,{registry:a,confirm:(h,m)=>this.confirmAction(a,h,m,i.signal),signal:i.signal,timeoutMs:this.config.actionTimeoutMs,...r,onStatus:h=>{c.status=h,this.updateMessage(e)}});p.error&&(c.error=p.error),this.updateMessage(e),o.push(p),this.emit("dewee:action",{phase:"result",id:p.id,name:p.name,sensitivity:u,args:f,status:p.status,result:p.result,error:p.error,...r})}}finally{this.setRunning(null)}return i.signal.aborted?null:o}confirmAction(e,n,i,o){let a=this.dom?.actions.includes(e.get(n.name))?this.dom.target(i):void 0,d=a?{...i,target:a}:i;return this.hooks.confirm?this.hooks.confirm(n,d):(this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),Pe(this.els.panel,this.strings,n,d,o))}showNotice(e){let n=document.createElement("div");n.className="notice",n.setAttribute("role","status"),n.textContent=e,this.els.log.appendChild(n),this.scrollToBottom(!0)}stop(){this.running?.abort()}async renewSession(){this.stop();try{await this.client().renewSession()}catch(e){this.showError(null,e);return}this.activated&&await this.loadConversation()}reuseHint(){return this.client().reuseHint()}async startLink(){this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),await this.activate();try{let e=await this.client().link();return this.renderLink(e),this.emit("dewee:link",{expiresAt:e.expiresAt,deepLinks:e.deepLinks}),e}catch(e){return this.showError(null,e),null}}async openJobAccess(){if(this.jobAccessLaunch)return;let e=new AbortController;this.jobAccessLaunch=e,this.els.jobAccess.disabled=!0;try{await _e(n=>this.client().jobAccess(n),e.signal),this.showNotice(this.strings.jobAccessOpened)}catch(n){if(e.signal.aborted)return;n instanceof A?this.showNotice(n.code==="popup_blocked"?this.strings.jobAccessPopupBlocked:n.code==="popup_closed"?this.strings.jobAccessPopupClosed:this.strings.jobAccessUnavailable):n instanceof E&&z(n.code)?this.showError(null,n):this.showNotice(this.strings.jobAccessUnavailable)}finally{this.jobAccessLaunch=null,this.els.jobAccess.disabled=!1}}renderLink(e){let n=this.strings,i=document.createElement("div");i.className="msg assistant link";let o=document.createElement("div");o.className="bubble";let r=document.createElement("div");r.className="md";let a=c=>{let u=document.createElement("p");return u.textContent=c,u},d=document.createElement("code");d.textContent=e.proofCode;let l=document.createElement("p");if(l.appendChild(d),r.append(a(n.linkIntro),l),e.deepLinks.length){let c=document.createElement("ul");for(let u of e.deepLinks){let f=document.createElement("li"),p=u.displayName||u.name;f.textContent=n.linkContinueOn(At(u.channelType))+(p?` \xB7 ${p}`:""),c.appendChild(f)}r.appendChild(c)}else r.appendChild(a(n.linkNoTargets));r.appendChild(a(n.linkExpires(Math.max(1,Math.round((e.expiresAt-Date.now())/6e4))))),o.appendChild(r),i.appendChild(o),this.messages.length||this.els.log.replaceChildren(),this.els.log.appendChild(i),this.scrollToBottom(!0)}newConversation(){this.stop(),this.conversationId=je(),this.config.persist!==!1&&_.set(this.convKey(),this.conversationId),this.messages=[],this.renderLog(),this.els.input.focus()}connectedCallback(){this.els||this.renderShell(),this.applyConfig(),(this.config.mode==="inline"||this.config.open)&&(this.config.mode!=="inline"?this.open():this.activate())}disconnectedCallback(){this.jobAccessLaunch?.abort(),this.stop(),this.mql?.removeEventListener("change",this.onScheme)}attributeChangedCallback(){this.els&&this.applyConfig()}emit(e,n){this.dispatchEvent(new CustomEvent(e,{detail:n,bubbles:!0,composed:!0}))}client(){let e=this.config,n=[e.endpoint,e.gatewayUrl,e.gatewayToken].join("|");return(!this.api||n!==this.apiKey)&&(this.apiKey=n,this.api=new R({endpoint:e.endpoint,gatewayUrl:e.gatewayUrl,gatewayToken:e.gatewayToken,turnstile:i=>this.challenge(i),headers:()=>{let i=this.hooks.headers;return(typeof i=="function"?i():i)??{}},fetch:(i,o)=>(this.hooks.fetch??globalThis.fetch)(i,o)})),this.api}convKey(){return`dewee-webchat:conv:${this.config.endpoint}:${this.config.gatewayUrl||""}:${this.agentId}`}applyTheme(){let e=this.config.theme||"light",n=e==="dark"||e==="auto"&&!!this.mql?.matches;this.setAttribute("data-theme",n?"dark":"light")}applyConfig(){let e=this.config;this.strings=ce(e.locale);let n=this.strings;this.setAttribute("data-position",e.position||"bottom-right"),this.setAttribute("data-mode",e.mode||"floating"),e.theme==="auto"&&!this.mql&&(this.mql=matchMedia("(prefers-color-scheme: dark)"),this.mql.addEventListener("change",this.onScheme)),this.applyTheme();let i=(r,a)=>a!==void 0&&a!==""?this.style.setProperty(r,String(a)):this.style.removeProperty(r);i("--dw-accent",e.accentColor),i("--dw-width",e.width),i("--dw-height",e.height),i("--dw-z",e.zIndex);let o=this.els;if(o.title.textContent=e.title||n.title,o.avatar.replaceChildren(),e.avatar){let r=document.createElement("img");r.src=e.avatar,r.alt="",o.avatar.appendChild(r)}else o.avatar.textContent=(e.title||n.title).trim().charAt(0).toUpperCase();if(o.launcher.innerHTML=e.avatar&&e.launcherAvatar?"":C.chat,e.avatar&&e.launcherAvatar){let r=document.createElement("img");r.src=e.avatar,r.alt="",o.launcher.appendChild(r)}o.launcher.insertAdjacentHTML("beforeend",'<span class="badge"></span>'),o.launcher.setAttribute("aria-label",n.open),o.close.setAttribute("aria-label",n.close),o.close.title=n.close,o.newChat.setAttribute("aria-label",n.newChat),o.newChat.title=n.newChat,o.jobAccess.setAttribute("aria-label",n.jobAccess),o.jobAccess.title=n.jobAccess,o.input.placeholder=e.placeholder||n.placeholder,o.foot.hidden=!!e.hideBranding,o.foot.querySelector(".by").textContent=n.poweredBy+" ",this.renderSubtitle(),this.updateSendButton(),this.activated&&this.api&&this.apiKey!==[e.endpoint,e.gatewayUrl,e.gatewayToken].join("|")?(this.activated=!1,this.server=null,this.activate()):this.activated&&e.agent&&e.agent!==this.agentId&&this.server?this.switchAgent(e.agent):this.activated&&this.renderLog()}renderShell(){this.root.innerHTML=`
309
- <style>${De}</style>
312
+ `;var Rt=5e3,Fe=["show-reasoning","show-tool-calls","allow-agent-switch","open","persist","hide-branding","launcher-avatar","dom-actions"],Ye=["endpoint","agent","title","subtitle","greeting","intro","placeholder","suggestions","avatar","position","mode","theme","accent-color","locale","gateway-url","gateway-token","width","height","z-index","dom-actions-root","image-origins","page-context","context-selector","exclude-selectors",...Fe],Ge=t=>t.replace(/-([a-z])/g,(s,e)=>e.toUpperCase()),_t=t=>t!==null&&!/^(false|0|off|no)$/i.test(t),We=()=>{let t=crypto.getRandomValues(new Uint8Array(9));return Array.from(t,s=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"[s&63]).join("")},Nt=t=>t.replace(/^mcp_[^_]+(?:_[^_]+)*?__/,"").replace(/_/g," "),_={get(t){try{return localStorage.getItem(t)}catch{return null}},set(t,s){try{localStorage.setItem(t,s)}catch{}}},Ot=null;function Ht(){return Ot??(Ot=new Promise((t,s)=>{if(window.turnstile)return t();let e=document.createElement("script");e.src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit",e.async=!0,e.onload=()=>t(),e.onerror=()=>s(new Error("Could not load Turnstile")),document.head.appendChild(e)}))}var Dt=typeof HTMLElement>"u"?class{}:HTMLElement,D=class extends Dt{constructor(){super();f(this,"root");f(this,"overrides",{});f(this,"api",null);f(this,"apiKey","");f(this,"server",null);f(this,"sharedPage");f(this,"preparingPage",!1);f(this,"pagePending",!1);f(this,"pageGeneration",0);f(this,"agentId","");f(this,"conversationId","");f(this,"messages",[]);f(this,"running",null);f(this,"jobAccessLaunch",null);f(this,"activated",!1);f(this,"probedPage",!1);f(this,"strings",ue());f(this,"mql",null);f(this,"registry",new O);f(this,"propActionNames",new Set);f(this,"hooks",{});f(this,"dom",null);f(this,"acks",new Map);f(this,"cooldown",new J(e=>this.renderCooldown(e),()=>this.endCooldown()));f(this,"els");f(this,"onScheme",()=>this.applyTheme());f(this,"pendingFrame",0);f(this,"following",!0);this.root=this.attachShadow({mode:"open"})}static get observedAttributes(){return Ye}get config(){let e={endpoint:"/api/dewee"};for(let n of Ye){let i=this.getAttribute(n);i!==null&&(Fe.includes(n)?e[Ge(n)]=_t(i):n==="suggestions"?e.suggestions=i.trim().startsWith("[")?ge(i,[]):i.split("|").map(r=>r.trim()).filter(Boolean):n==="image-origins"?e.imageOrigins=i.trim().startsWith("[")?ge(i,[]):i.split(",").map(r=>r.trim()).filter(Boolean):n==="exclude-selectors"?e.excludeSelectors=i.trim().startsWith("[")?ge(i,[]):i.split(",").map(r=>r.trim()).filter(Boolean):n==="z-index"?e.zIndex=Number(i):e[Ge(n)]=i)}return{...e,...this.overrides,...this.hooks}}configure(e){let{actions:n,confirm:i,getPageContext:r,headers:o,fetch:c,domActionsRoot:a,contextProvider:d,...l}=e,p=g=>Object.prototype.hasOwnProperty.call(e,g);p("actions")&&this.setPropActions(n??[]),p("confirm")&&(this.hooks.confirm=i),p("getPageContext")&&(this.hooks.getPageContext=r),p("headers")&&(this.hooks.headers=o),p("fetch")&&(this.hooks.fetch=c),p("contextProvider")&&(this.hooks.contextProvider=d),p("domActionsRoot")&&(a===void 0?delete this.hooks.domActionsRoot:this.hooks.domActionsRoot=a),Object.keys(l).length&&(this.overrides={...this.overrides,...l},this.els&&this.applyConfig())}registerActions(e){this.registry.register(e)}unregisterAction(e){return this.propActionNames.delete(e),this.registry.unregister(e)}get headers(){return this.hooks.headers}set headers(e){this.hooks.headers=e}get fetch(){return this.hooks.fetch}set fetch(e){this.hooks.fetch=e}get actionNames(){return this.actionRegistry().names()}actionRegistry(){if(!this.config.domActions)return this.registry;this.dom??(this.dom=Ne({root:()=>this.hooks.domActionsRoot??this.getAttribute("dom-actions-root")??void 0,exclude:o=>o===this||this.contains(o)||o.closest("dewee-chat")!==null}));let e=this.registry.names().map(o=>this.registry.get(o)),n=S.maxActions-e.length,i=this.dom.actions.filter(o=>!this.registry.get(o.name)).slice(0,Math.max(0,n)),r=new O;return r.register([...e,...i]),r}setPropActions(e){let n=new Set(e.map(i=>i.name));for(let i of this.propActionNames)n.has(i)||this.registry.unregister(i);e.length&&this.registry.register(e),this.propActionNames=n}open(){this.config.mode!=="inline"&&(this.setAttribute("data-open",""),this.removeAttribute("data-unread"),this.els.launcher.setAttribute("aria-expanded","true"),this.activate(),setTimeout(()=>this.els.input.focus(),120),this.emit("dewee:open"))}close(){this.config.mode!=="inline"&&(this.removeAttribute("data-open"),this.els.launcher.setAttribute("aria-expanded","false"),this.emit("dewee:close"))}toggle(){this.hasAttribute("data-open")?this.close():this.open()}async send(e){let n=e.trim();if(!n||this.running||this.preparingPage||this.cooldown.active)return;this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),await this.activate();let i;if(this.els.pageChoice.checked){if(this.pagePending){this.showNotice(this.strings.pageUnavailable);return}this.preparingPage=!0;let o=this.pageGeneration;try{let c=this.sharedPage,a=await this.captureCurrentPage();if(!this.els.pageChoice.checked||o!==this.pageGeneration)return;if(!c||!a||this.pageFingerprint(c)!==this.pageFingerprint(a)){this.sharedPage=a,this.renderPagePreview(),this.els.pageChoice.checked=!1,this.showNotice(this.strings.pageChanged);return}i=a}catch{this.sharedPage=void 0,this.els.pageChoice.checked=!1,this.renderPagePreview(),this.showNotice(this.strings.pageUnavailable);return}finally{this.preparingPage=!1}this.els.pageChoice.checked=!1,this.sharedPage=void 0,this.renderPagePreview()}this.els.input.value="",this.autosize();let r={message:n,hidden:!1};for(let o=0;r;o++){let c=await this.runTurn(r.message,r.hidden,o===0?i:void 0);if(r=null,c.status!=="done"||c.stopped||!this.actionRegistry().size)break;let{calls:a}=X(c.content);if(!a.length)break;c.actions=a.map(p=>({id:p.id,name:p.name,args:p.ok?p.args:void 0,status:"pending"}));let d=this.config.maxActionRounds??5;if(o>=d){for(let p of c.actions)Object.assign(p,{status:"error",error:"Automatic action limit reached"});this.updateMessage(c),this.showNotice(this.strings.actionLimit(d));break}this.updateMessage(c);let l=await this.runActions(c,a);l&&(r={message:Te(l,this.server?.maxMessageLength??4e3),hidden:!0})}}async runTurn(e,n,i){this.pushMessage({role:"user",content:e,hidden:n});let r={role:"assistant",content:"",status:"streaming",startedAt:Date.now()};this.pushMessage(r),this.setRunning(new AbortController),this.emit("dewee:send",{message:e,agent:this.agentId,conversationId:this.conversationId,auto:n||void 0});try{await this.client().ensureSession(),await this.client().chat({...this.chatBody(e),...i?{page_context:i}:{}},o=>this.onStreamEvent(r,o),this.running.signal),r.status==="streaming"&&(r.status="done")}catch(o){o.name==="AbortError"?(r.status="done",r.stopped=!0,r.content||(r.content=`_${this.strings.stopped}_`)):(r.status="error",this.showError(r,o))}finally{this.finishThinking(r),this.updateMessage(r),this.setRunning(null),r.status==="done"&&(r.actionsHash&&r.ackVisitor&&!r.stopped&&this.setAck(r.actionsHash,r.ackVisitor),this.emit("dewee:reply",{content:r.content,agent:this.agentId,conversationId:this.conversationId}),this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.setAttribute("data-unread",""))}return r}chatBody(e){let n={message:e,agent:this.agentId,conversationId:this.conversationId},i=this.actionRegistry();if(i.size){n.actions=i.manifest();let o=this.client().visitorId(),c=o?this.getAck(o):void 0;c&&(n.actionsHash=c)}let r=this.pageContext();return r!==void 0&&(n.pageContext=r),n}pageContext(){let e=this.hooks.getPageContext;if(e)try{let n=e();if(n==null)return;let i=new TextEncoder().encode(JSON.stringify(n)).length;return i<=S.maxPageContextBytes?n:(console.warn(`[dewee-webchat] getPageContext() returned ${i} bytes; the limit is ${S.maxPageContextBytes}. Context not sent.`),{truncated:!0})}catch(n){console.warn("[dewee-webchat] getPageContext() failed:",n);return}}ackKey(e){return`dewee-webchat:actions:${this.config.endpoint}:${this.agentId}:${e}:${this.conversationId}`}getAck(e){let n=this.ackKey(e);return this.acks.get(n)??(this.config.persist!==!1?_.get(n)??void 0:void 0)}setAck(e,n){let i=this.ackKey(n);this.acks.set(i,e),this.config.persist!==!1&&_.set(i,e)}async runActions(e,n){let i=new AbortController;this.setRunning(i);let r=[],o={agent:this.agentId,conversationId:this.conversationId},c=this.actionRegistry();try{for(let[a,d]of n.entries()){let l=e.actions[a],p=d.ok?c.get(d.name)?.sensitivity:void 0,g=d.ok?d.args:void 0;this.emit("dewee:action",{phase:"start",id:d.id,name:d.name,sensitivity:p,args:g,...o});let h=await Re(d,{registry:c,confirm:(u,m)=>this.confirmAction(c,u,m,i.signal),signal:i.signal,timeoutMs:this.config.actionTimeoutMs,...o,onStatus:u=>{l.status=u,this.updateMessage(e)}});h.error&&(l.error=h.error),this.updateMessage(e),r.push(h),this.emit("dewee:action",{phase:"result",id:h.id,name:h.name,sensitivity:p,args:g,status:h.status,result:h.result,error:h.error,...o})}}finally{this.setRunning(null)}return i.signal.aborted?null:r}confirmAction(e,n,i,r){let c=this.dom?.actions.includes(e.get(n.name))?this.dom.target(i):void 0,a=c?{...i,target:c}:i;return this.hooks.confirm?this.hooks.confirm(n,a):(this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),je(this.els.panel,this.strings,n,a,r))}showNotice(e){let n=document.createElement("div");n.className="notice",n.setAttribute("role","status"),n.textContent=e,this.els.log.appendChild(n),this.scrollToBottom(!0)}stop(){this.running?.abort()}async renewSession(){this.stop();try{await this.client().renewSession()}catch(e){this.showError(null,e);return}this.activated&&await this.loadConversation()}reuseHint(){return this.client().reuseHint()}async startLink(){this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),await this.activate();try{let e=await this.client().link();return this.renderLink(e),this.emit("dewee:link",{expiresAt:e.expiresAt,deepLinks:e.deepLinks}),e}catch(e){return this.showError(null,e),null}}async openJobAccess(){if(this.jobAccessLaunch)return;let e=new AbortController;this.jobAccessLaunch=e,this.els.jobAccess.disabled=!0;try{await $e(n=>this.client().jobAccess(n),e.signal),this.showNotice(this.strings.jobAccessOpened)}catch(n){if(e.signal.aborted)return;n instanceof A?this.showNotice(n.code==="popup_blocked"?this.strings.jobAccessPopupBlocked:n.code==="popup_closed"?this.strings.jobAccessPopupClosed:this.strings.jobAccessUnavailable):n instanceof E&&Y(n.code)?this.showError(null,n):this.showNotice(this.strings.jobAccessUnavailable)}finally{this.jobAccessLaunch=null,this.els.jobAccess.disabled=!1}}renderLink(e){let n=this.strings,i=document.createElement("div");i.className="msg assistant link";let r=document.createElement("div");r.className="bubble";let o=document.createElement("div");o.className="md";let c=l=>{let p=document.createElement("p");return p.textContent=l,p},a=document.createElement("code");a.textContent=e.proofCode;let d=document.createElement("p");if(d.appendChild(a),o.append(c(n.linkIntro),d),e.deepLinks.length){let l=document.createElement("ul");for(let p of e.deepLinks){let g=document.createElement("li"),h=p.displayName||p.name;g.textContent=n.linkContinueOn(Bt(p.channelType))+(h?` \xB7 ${h}`:""),l.appendChild(g)}o.appendChild(l)}else o.appendChild(c(n.linkNoTargets));o.appendChild(c(n.linkExpires(Math.max(1,Math.round((e.expiresAt-Date.now())/6e4))))),r.appendChild(o),i.appendChild(r),this.messages.length||this.els.log.replaceChildren(),this.els.log.appendChild(i),this.scrollToBottom(!0)}newConversation(){this.stop(),this.conversationId=We(),this.config.persist!==!1&&_.set(this.convKey(),this.conversationId),this.messages=[],this.renderLog(),this.els.input.focus()}connectedCallback(){this.els||this.renderShell(),this.applyConfig(),(this.config.mode==="inline"||this.config.open)&&(this.config.mode!=="inline"?this.open():this.activate())}disconnectedCallback(){this.pageGeneration++,this.sharedPage=void 0,this.els.pageChoice.checked=!1,this.renderPagePreview(),U(this.root);for(let e of this.messages)e.view&&(e.view.mdKey=void 0);this.jobAccessLaunch?.abort(),this.stop(),this.mql?.removeEventListener("change",this.onScheme)}attributeChangedCallback(){this.els&&this.applyConfig()}emit(e,n){this.dispatchEvent(new CustomEvent(e,{detail:n,bubbles:!0,composed:!0}))}client(){let e=this.config,n=[e.endpoint,e.gatewayUrl,e.gatewayToken].join("|");return(!this.api||n!==this.apiKey)&&(this.apiKey=n,this.api=new M({endpoint:e.endpoint,gatewayUrl:e.gatewayUrl,gatewayToken:e.gatewayToken,turnstile:i=>this.challenge(i),headers:()=>{let i=this.hooks.headers;return(typeof i=="function"?i():i)??{}},fetch:(i,r)=>(this.hooks.fetch??globalThis.fetch)(i,r)})),this.api}convKey(){return`dewee-webchat:conv:${this.config.endpoint}:${this.config.gatewayUrl||""}:${this.agentId}`}applyTheme(){let e=this.config.theme||"light",n=e==="dark"||e==="auto"&&!!this.mql?.matches;this.setAttribute("data-theme",n?"dark":"light")}applyConfig(){let e=this.config;this.strings=ue(e.locale);let n=this.strings;this.setAttribute("data-position",e.position||"bottom-right"),this.setAttribute("data-mode",e.mode||"floating"),e.theme==="auto"&&!this.mql&&(this.mql=matchMedia("(prefers-color-scheme: dark)"),this.mql.addEventListener("change",this.onScheme)),this.applyTheme();let i=(o,c)=>c!==void 0&&c!==""?this.style.setProperty(o,String(c)):this.style.removeProperty(o);i("--dw-accent",e.accentColor),i("--dw-width",e.width),i("--dw-height",e.height),i("--dw-z",e.zIndex);let r=this.els;if(r.title.textContent=e.title||n.title,r.avatar.replaceChildren(),e.avatar){let o=document.createElement("img");o.src=e.avatar,o.alt="",r.avatar.appendChild(o)}else r.avatar.textContent=(e.title||n.title).trim().charAt(0).toUpperCase();if(r.launcher.innerHTML=e.avatar&&e.launcherAvatar?"":C.chat,e.avatar&&e.launcherAvatar){let o=document.createElement("img");o.src=e.avatar,o.alt="",r.launcher.appendChild(o)}if(r.launcher.insertAdjacentHTML("beforeend",'<span class="badge"></span>'),r.launcher.setAttribute("aria-label",n.open),r.close.setAttribute("aria-label",n.close),r.close.title=n.close,r.newChat.setAttribute("aria-label",n.newChat),r.newChat.title=n.newChat,r.jobAccess.setAttribute("aria-label",n.jobAccess),r.jobAccess.title=n.jobAccess,r.input.placeholder=e.placeholder||n.placeholder,r.pageLabel.textContent=n.pageShare,this.updatePageChoice(),r.foot.hidden=!!e.hideBranding,r.foot.querySelector(".by").textContent=n.poweredBy+" ",this.renderSubtitle(),this.updateSendButton(),this.activated&&this.api&&this.apiKey!==[e.endpoint,e.gatewayUrl,e.gatewayToken].join("|"))this.activated=!1,this.server=null,this.probedPage=!1,this.activate();else if(this.activated&&!this.probedPage&&(e.pageContext==="metadata"||e.pageContext==="content"))this.activated=!1,this.activate();else if(this.activated&&e.agent&&e.agent!==this.agentId&&this.server)this.switchAgent(e.agent);else if(this.activated)if(!this.messages.length)this.renderLog();else for(let o of this.messages)this.updateMessage(o)}renderShell(){this.root.innerHTML=`
313
+ <style>${qe}</style>
310
314
  <button class="launcher" part="launcher" aria-expanded="false" aria-haspopup="dialog"></button>
311
315
  <section class="panel" part="panel" role="dialog" aria-label="Chat">
312
316
  <header class="head" part="header">
@@ -322,6 +326,7 @@ textarea::placeholder { color: var(--dw-muted); }
322
326
  <div class="log" part="log" role="log" aria-live="polite"></div>
323
327
  <div class="challenge"><slot name="challenge"></slot></div>
324
328
  <form class="composer" part="composer">
329
+ <div class="page-context" hidden><label><input type="checkbox" class="page-choice"> <span class="page-label"></span></label><pre class="page-preview" hidden></pre></div>
325
330
  <div class="cooldown" part="cooldown" aria-hidden="true" hidden></div>
326
331
  <div class="sr-only announcer" role="status" aria-live="polite"></div>
327
332
  <div class="box">
@@ -330,7 +335,9 @@ textarea::placeholder { color: var(--dw-muted); }
330
335
  </div>
331
336
  <div class="foot"><span><span class="by"></span><a href="https://dewee.sh" target="_blank" rel="noopener">dewee</a></span><span class="meta"></span></div>
332
337
  </form>
333
- </section>`;let e=i=>this.root.querySelector(i);this.els={launcher:e(".launcher"),panel:e(".panel"),log:e(".log"),title:e(".title"),subtitle:e(".subtitle"),status:e(".status"),avatar:e(".avatar"),select:e(".agent-select"),input:e("textarea"),send:e(".send"),newChat:e(".new"),jobAccess:e(".job-access"),close:e(".close"),foot:e(".foot"),cooldown:e(".cooldown"),announcer:e(".announcer")};let n=this.els;n.launcher.addEventListener("click",()=>this.toggle()),n.close.addEventListener("click",()=>this.close()),n.log.addEventListener("scroll",()=>{this.following=this.nearBottom()},{passive:!0}),n.newChat.addEventListener("click",()=>this.newConversation()),n.jobAccess.addEventListener("click",()=>{this.openJobAccess()}),n.select.addEventListener("change",()=>this.switchAgent(n.select.value)),e("form").addEventListener("submit",i=>{i.preventDefault(),this.running?this.stop():this.send(n.input.value)}),n.input.addEventListener("keydown",i=>{i.key==="Enter"&&!i.shiftKey&&!i.isComposing&&i.keyCode!==229&&(i.preventDefault(),this.running||this.send(n.input.value))}),n.input.addEventListener("input",()=>{this.autosize(),this.updateSendButton()}),n.panel.addEventListener("keydown",i=>{i.key==="Escape"&&this.close()})}autosize(){let e=this.els.input;e.style.height="auto",e.style.height=Math.min(e.scrollHeight,140)+"px"}updateSendButton(){let e=this.els.send;e.innerHTML=this.running?C.stop:C.send,e.setAttribute("aria-label",this.running?this.strings.stop:this.strings.send),e.title=e.getAttribute("aria-label"),e.disabled=!this.running&&(this.cooldown.active||!this.els.input.value.trim())}startCooldown(e){this.cooldown.start(typeof e=="number"&&Number.isFinite(e)&&e>0?e:mt),this.cooldown.active&&(this.renderCooldown(this.cooldown.secondsLeft),this.els.announcer.textContent=this.strings.cooldownStart(this.cooldown.secondsLeft),this.updateSendButton())}renderCooldown(e){this.els.cooldown.hidden=!1,this.els.cooldown.textContent=this.strings.cooldown(e)}endCooldown(){this.els.cooldown.hidden=!0,this.els.cooldown.textContent="",this.els.announcer.textContent=this.strings.cooldownOver,this.updateSendButton()}setRunning(e){this.running=e,this.updateSendButton()}renderSubtitle(){this.els.jobAccess.hidden=this.server?.identity!==!0;let e=this.els,n=this.config,i=this.server?.agents??[],o=n.allowAgentSwitch!==!1&&!!this.server?.allowAgentSwitch&&i.length>1;e.select.hidden=!o,e.status.hidden=o,o&&(e.select.replaceChildren(...i.map(a=>new Option(a.name||a.id,a.id,!1,a.id===this.agentId))),e.select.setAttribute("aria-label","Agent"));let r=i.find(a=>a.id===this.agentId);e.status.textContent=n.subtitle||(r?.name&&r.name!==n.title?`${this.strings.online} \xB7 ${r.name}`:this.strings.online)}async activate(){if(!this.activated){this.activated=!0,this.renderLog();try{this.server=await this.client().getConfig(!0),this.els.input.maxLength=this.server.maxMessageLength;let e=this.config.agent,n=i=>!!i&&(this.server.agents.length===0||this.server.agents.some(o=>o.id===i));this.agentId=n(e)?e:this.server.defaultAgent||this.server.agents[0]?.id||e||"",await this.loadConversation()}catch(e){this.activated=!1,this.renderLog(),this.showError(null,e)}this.renderSubtitle(),this.emit("dewee:ready",{agent:this.agentId,config:this.server})}}async switchAgent(e){e!==this.agentId&&(this.stop(),this.agentId=e,this.renderSubtitle(),await this.loadConversation())}async loadConversation(){let e=this.config.persist!==!1,n=e?_.get(this.convKey()):null;if(this.conversationId=n||je(),e&&!n&&_.set(this.convKey(),this.conversationId),this.messages=[],this.renderLog(),!!n)try{let i=await this.client().history(this.agentId,this.conversationId);this.messages=Et(i.map(o=>({...o,status:"done"}))),this.renderLog()}catch{}}renderLog(){let e=this.els.log;e.replaceChildren(),this.messages.length||e.appendChild(this.renderWelcome());for(let n of this.messages)e.appendChild(this.renderMessage(n));e.scrollTop=e.scrollHeight}renderWelcome(){let e=this.config,n=this.strings,i=document.createElement("div");i.className="welcome";let o=document.createElement("h2");o.textContent=e.greeting||n.greeting;let r=document.createElement("p");if(r.textContent=e.intro||n.greetingBody,i.append(o,r),e.suggestions?.length){let a=document.createElement("div");a.className="suggestions";for(let d of e.suggestions){let l=document.createElement("button");l.className="chip",l.type="button",l.textContent=d,l.addEventListener("click",()=>this.send(d)),a.appendChild(l)}i.appendChild(a)}return i}pushMessage(e){this.messages.length||this.els.log.replaceChildren(),this.messages.push(e),this.els.log.appendChild(this.renderMessage(e)),this.scrollToBottom(!0)}renderMessage(e){let n=document.createElement("div");n.className=`msg ${e.role}${e.status==="error"?" error":""}`,n.hidden=!!e.hidden;let i=document.createElement("div");i.className="bubble",n.appendChild(i);let o=document.createElement("div");o.className="trace";let r=document.createElement("div");r.className=e.role==="assistant"?"md":"";let a=document.createElement("div");return a.className="actions",a.hidden=!0,e.role==="assistant"&&i.appendChild(o),i.appendChild(r),e.role==="assistant"&&i.appendChild(a),e.view={root:n,trace:o,md:r,tools:new Map,actions:a},this.updateMessage(e),n}updateMessage(e){let n=e.view;if(!n)return;let i=this.config;if(e.role==="user"){n.md.textContent=e.content,n.root.classList.toggle("refused",!!e.refusal);let a=n.root.querySelector(".refusal");e.refusal&&!a&&(a=document.createElement("div"),a.className="refusal",n.root.appendChild(a)),a&&e.refusal?a.textContent=`\u26A0\uFE0F ${e.refusal}`:a?.remove();return}if(n.root.classList.toggle("error",e.status==="error"),i.showReasoning!==!1&&e.thinking){n.thinking||(n.thinking=document.createElement("details"),n.thinking.className="thinking",n.thinking.innerHTML='<summary></summary><div class="thinking-body"></div>',n.trace.prepend(n.thinking));let a=e.status==="streaming"&&!e.thinkingMs,d=a?this.strings.thinking:e.thinkingMs?this.strings.thoughtFor(Math.max(1,Math.round(e.thinkingMs/1e3))):this.strings.reasoning,l=n.thinking.querySelector("summary");l.innerHTML=`${a?'<span class="spin"></span>':C.brain}<span></span>${C.down.replace("<svg",'<svg class="chev"')}`,l.querySelector("span:not(.spin)").textContent=d,n.thinking.querySelector(".thinking-body").textContent=e.thinking}else n.thinking&&(n.thinking.remove(),n.thinking=void 0);if(i.showToolCalls!==!1)for(let a of e.toolCalls??[])this.renderTool(n,a);else n.tools.forEach(a=>a.remove()),n.tools.clear();n.trace.hidden=!n.trace.childElementCount;let o=this.actionRegistry().size||e.actions?ye(e.content):e.content,r=e.status==="streaming"&&!o;n.md.hidden=!r&&!o&&!!e.actions?.length,r?n.md.innerHTML=`<span class="typing" aria-label="${this.strings.thinking}"><i></i><i></i><i></i></span>`:(n.md.replaceChildren(M(document,o)),n.md.classList.toggle("cursor",e.status==="streaming")),this.renderActions(n,e.actions??[])}renderActions(e,n){e.actions.hidden=!n.length,e.actions.replaceChildren(...n.map(i=>{let o=document.createElement("div");o.className="action",o.dataset.status=i.status;let r=i.status==="running"||i.status==="awaiting-confirmation";o.innerHTML=`${r?'<span class="spin"></span>':C.action}<span class="action-name"></span><span class="action-state"></span>`,o.querySelector(".action-name").textContent=i.name||"?",o.querySelector(".action-state").textContent=this.strings.actionStatus[i.status];let a=[i.args&&Object.keys(i.args).length?JSON.stringify(i.args):"",i.error??""].filter(Boolean).join(`
334
- `);return a&&(o.title=a),o}))}renderTool(e,n){let i=e.tools.get(n.id);i||(i=document.createElement("details"),i.className="tool",i.innerHTML=`<summary><span class="lead"></span><span class="tool-name"></span><span class="tool-state"></span>${C.down.replace("<svg",'<svg class="chev"')}</summary><div class="tool-body"></div>`,e.tools.set(n.id,i),e.trace.appendChild(i)),i.dataset.status=n.status,i.querySelector(".lead").innerHTML=n.status==="running"?'<span class="spin"></span>':C.tool;let o=i.querySelector(".tool-name");o.textContent=wt(n.name),o.setAttribute("title",n.name),i.querySelector(".tool-state").textContent=n.status==="running"?this.strings.toolRunning:n.status==="error"?this.strings.toolError:this.strings.toolDone;let r=i.querySelector(".tool-body");r.replaceChildren();let a=(d,l)=>{if(l==null||l==="")return;let c=document.createElement("div");c.className="label",c.textContent=d;let u=document.createElement("pre");u.textContent=typeof l=="string"?St(l):JSON.stringify(l,null,2),r.append(c,u)};a(this.strings.args,n.arguments),a(this.strings.result,n.result)}onStreamEvent(e,n){switch(n.type){case"start":n.actionsHash&&(e.actionsHash=n.actionsHash,e.ackVisitor=this.client().visitorId()??void 0),n.conversationId&&n.conversationId!==this.conversationId&&(this.conversationId=n.conversationId,this.config.persist!==!1&&_.set(this.convKey(),n.conversationId));break;case"thinking":e.thinking=(e.thinking||"")+n.text;break;case"delta":this.finishThinking(e),e.content+=n.text;break;case"tool_call":this.finishThinking(e),(e.toolCalls??(e.toolCalls=[])).push({id:n.id,name:n.name,arguments:n.arguments,status:"running"});break;case"tool_result":{let i=e.toolCalls?.find(o=>o.id===n.id)??(e.toolCalls??(e.toolCalls=[]))[e.toolCalls.push({id:n.id,name:n.name,status:"running"})-1];i.status=n.isError?"error":"done",i.result=n.result,i.isError=n.isError;break}case"done":this.finishThinking(e),n.content&&n.content.length>=e.content.length&&(e.content=n.content),e.status="done";break;case"error":e.status="error",this.showError(e,new E(n.message,500,n.code,n.remediation,n.retryAfterMs));break}this.scheduleUpdate(e)}scheduleUpdate(e){this.pendingFrame||(this.pendingFrame=requestAnimationFrame(()=>{this.pendingFrame=0,this.updateMessage(e),this.following&&this.scrollToBottom(!0)}))}finishThinking(e){e.thinking&&!e.thinkingMs&&e.startedAt&&(e.thinkingMs=Date.now()-e.startedAt)}nearBottom(){let e=this.els.log;return e.scrollHeight-e.scrollTop-e.clientHeight<96}scrollToBottom(e=!1){let n=this.els.log;(e||this.nearBottom())&&(n.scrollTop=n.scrollHeight,this.following=!0)}showError(e,n){let{code:i,remediation:o,retryAfterMs:r}=n,d=(z(i)?this.strings.identityErrors[i]:q(i)?this.strings.admissionErrors[i]:pe(i)?this.strings.linkErrors[i]:"")||n.message||this.strings.errorGeneric;if(this.emit("dewee:error",{message:d,code:i,...o&&{remediation:o},...r&&{retryAfterMs:r}}),i==="RATE_LIMITED"&&this.startCooldown(r),e&&q(i)&&this.refuseInline(e,i,d))return;if(e){e.content=e.content?`${e.content}
338
+ </section>`;let e=i=>this.root.querySelector(i);this.els={launcher:e(".launcher"),panel:e(".panel"),log:e(".log"),title:e(".title"),subtitle:e(".subtitle"),status:e(".status"),avatar:e(".avatar"),select:e(".agent-select"),input:e("textarea"),send:e(".send"),newChat:e(".new"),jobAccess:e(".job-access"),close:e(".close"),foot:e(".foot"),cooldown:e(".cooldown"),announcer:e(".announcer"),pageChoice:e(".page-choice"),pageWrap:e(".page-context"),pageLabel:e(".page-label"),pagePreview:e(".page-preview")};let n=this.els;n.launcher.addEventListener("click",()=>this.toggle()),n.close.addEventListener("click",()=>this.close()),n.log.addEventListener("scroll",()=>{this.following=this.nearBottom()},{passive:!0}),n.newChat.addEventListener("click",()=>this.newConversation()),n.jobAccess.addEventListener("click",()=>{this.openJobAccess()}),n.pageChoice.addEventListener("change",()=>{this.choosePage()}),n.select.addEventListener("change",()=>this.switchAgent(n.select.value)),e("form").addEventListener("submit",i=>{i.preventDefault(),this.running?this.stop():this.send(n.input.value)}),n.input.addEventListener("keydown",i=>{i.key==="Enter"&&!i.shiftKey&&!i.isComposing&&i.keyCode!==229&&(i.preventDefault(),this.running||this.send(n.input.value))}),n.input.addEventListener("input",()=>{this.autosize(),this.updateSendButton()}),n.panel.addEventListener("keydown",i=>{i.key==="Escape"&&this.close()})}autosize(){let e=this.els.input;e.style.height="auto",e.style.height=Math.min(e.scrollHeight,140)+"px"}updatePageChoice(){let e=this.config.pageContext,n=(e==="metadata"||e==="content")&&this.server?.pageContextVersions?.includes(1)===!0;this.els.pageWrap.hidden=!n,n||(this.pageGeneration++,this.pagePending=!1,this.els.pageChoice.checked=!1,this.sharedPage=void 0,this.renderPagePreview())}async captureCurrentPage(){let e=this.config;if(e.pageContext!=="metadata"&&e.pageContext!=="content"||!this.server?.pageContextVersions?.includes(1))return;let n=document.location.href,{capturePageContext:i,providedPageContext:r}=await Promise.resolve().then(()=>(Ke(),Ve)),o=this.hooks.contextProvider,c=JSON.stringify([e.pageContext,e.contextSelector,e.excludeSelectors]),a=i(document,{mode:o?"metadata":e.pageContext,selector:e.contextSelector,excludeSelectors:e.excludeSelectors}),d=a;if(a&&o){let p;try{let g=await Promise.race([o(),new Promise((h,u)=>{p=setTimeout(()=>u(new Error("Page context timed out")),5e3)})]);d=r(g,a,e.pageContext)}finally{p&&clearTimeout(p)}}let l=this.config;if(!(!this.isConnected||n!==document.location.href||o!==this.hooks.contextProvider||c!==JSON.stringify([l.pageContext,l.contextSelector,l.excludeSelectors])))return d}pageFingerprint(e){let{captured_at:n,...i}=e;return JSON.stringify(i)}renderPagePreview(){let e=this.els.pagePreview;e.hidden=!this.sharedPage,e.textContent=this.sharedPage?[this.sharedPage.title,this.sharedPage.url,this.sharedPage.description,this.sharedPage.selection,this.sharedPage.content?.text].filter(Boolean).join(`
335
339
 
336
- > \u26A0\uFE0F ${d}`:`\u26A0\uFE0F ${d}`,e.status="error",this.updateMessage(e);return}let l=document.createElement("div");l.className="msg error",l.innerHTML='<div class="bubble"></div>',l.firstElementChild.textContent=`\u26A0\uFE0F ${d}`,this.els.log.appendChild(l)}refuseInline(e,n,i){let o=this.messages.indexOf(e),r=o>0?this.messages[o-1]:void 0;return r?.role!=="user"||r.hidden||(this.els.input.value.trim()||(this.els.input.value=r.content,this.autosize()),n!=="POLICY_DENIED"||e.content)?!1:(e.status="error",e.hidden=!0,e.view&&(e.view.root.hidden=!0),r.refusal=i,this.updateMessage(r),!0)}async challenge(e){await xt();let n=document.createElement("div");n.slot="challenge",this.appendChild(n);try{return await new Promise((i,o)=>{window.turnstile.render(n,{sitekey:e,appearance:"interaction-only",theme:this.getAttribute("data-theme")==="dark"?"dark":"light",callback:i,"error-callback":()=>o(new E("Verification failed",403,"turnstile_failed"))})})}finally{n.remove()}}};function Et(t){return t.forEach((s,e)=>{if(s.role==="user"){s.content=Q(s.content),Y(s.content)&&(s.hidden=!0);return}if(!s.content.includes("```dewee-action"))return;let{calls:n}=K(s.content);if(!n.length)return;let i=t[e+1],o=i?.role==="user"?Q(i.content):"",r=Y(o)?xe(o):[];s.actions=n.map(a=>{let d=r.find(c=>c.id===a.id),l=d?d.status==="ok"?"done":d.status:"error";return{id:a.id,name:a.name,args:a.ok?a.args:void 0,status:l,error:d?d.error:"Not run"}})}),t}var kt={telegram:"Telegram",discord:"Discord",zalo:"Zalo",slack:"Slack",whatsapp:"WhatsApp",messenger:"Messenger",feishu:"Feishu",line:"LINE"};function At(t){let s=t.toLowerCase().split(/[_-]/)[0];return kt[s]??(t?t.charAt(0).toUpperCase()+t.slice(1):"chat")}function Ct(t,s){try{return JSON.parse(t)}catch{return s}}function St(t){let s=t.trim();if(!/^[[{]/.test(s))return t;try{return JSON.stringify(JSON.parse(s),null,2)}catch{return t}}function le(t="dewee-chat"){typeof window>"u"||!window.customElements||customElements.get(t)||customElements.define(t,class extends H{})}function Tt(t={},s){le();let e=document.createElement("dewee-chat");return e.configure(t),((typeof s=="string"?document.querySelector(s):s)??document.body).appendChild(e),e}le();var It=document.currentScript,B=It?.dataset;if(B&&B.endpoint&&B.autoMount!=="false"){let t=()=>{let s=document.createElement("dewee-chat");for(let[e,n]of Object.entries(B))e==="autoMount"||n===void 0||s.setAttribute(e.replace(/[A-Z]/g,i=>"-"+i.toLowerCase()),n);document.body.appendChild(s)};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",t):t()}window.DeweeWebchat=de;})();
340
+ `):""}async choosePage(){let e=++this.pageGeneration;if(!this.els.pageChoice.checked){this.pagePending=!1,this.sharedPage=void 0,this.renderPagePreview();return}this.sharedPage=void 0,this.renderPagePreview(),this.pagePending=!0;try{let n=await this.captureCurrentPage();if(e!==this.pageGeneration||!this.els.pageChoice.checked)return;if(!n)throw new Error("Page unavailable");this.sharedPage=n,this.renderPagePreview(),this.emit("dewee:context-ready",{available:!0})}catch{if(e!==this.pageGeneration)return;this.sharedPage=void 0,this.els.pageChoice.checked=!1,this.renderPagePreview(),this.showNotice(this.strings.pageUnavailable),this.emit("dewee:context-error",{code:"page_unavailable"})}finally{e===this.pageGeneration&&(this.pagePending=!1)}}updateSendButton(){let e=this.els.send;e.innerHTML=this.running?C.stop:C.send,e.setAttribute("aria-label",this.running?this.strings.stop:this.strings.send),e.title=e.getAttribute("aria-label"),e.disabled=!this.running&&(this.cooldown.active||!this.els.input.value.trim())}startCooldown(e){this.cooldown.start(typeof e=="number"&&Number.isFinite(e)&&e>0?e:Rt),this.cooldown.active&&(this.renderCooldown(this.cooldown.secondsLeft),this.els.announcer.textContent=this.strings.cooldownStart(this.cooldown.secondsLeft),this.updateSendButton())}renderCooldown(e){this.els.cooldown.hidden=!1,this.els.cooldown.textContent=this.strings.cooldown(e)}endCooldown(){this.els.cooldown.hidden=!0,this.els.cooldown.textContent="",this.els.announcer.textContent=this.strings.cooldownOver,this.updateSendButton()}setRunning(e){this.running=e,this.updateSendButton()}renderSubtitle(){this.els.jobAccess.hidden=this.server?.identity!==!0;let e=this.els,n=this.config,i=this.server?.agents??[],r=n.allowAgentSwitch!==!1&&!!this.server?.allowAgentSwitch&&i.length>1;e.select.hidden=!r,e.status.hidden=r,r&&(e.select.replaceChildren(...i.map(c=>new Option(c.name||c.id,c.id,!1,c.id===this.agentId))),e.select.setAttribute("aria-label","Agent"));let o=i.find(c=>c.id===this.agentId);e.status.textContent=n.subtitle||(o?.name&&o.name!==n.title?`${this.strings.online} \xB7 ${o.name}`:this.strings.online)}async activate(){if(!this.activated){this.activated=!0,this.renderLog();try{this.probedPage=this.config.pageContext==="metadata"||this.config.pageContext==="content",this.server=await this.client().getConfig(!0,this.probedPage),this.els.input.maxLength=this.server.maxMessageLength;let e=this.config.agent,n=i=>!!i&&(this.server.agents.length===0||this.server.agents.some(r=>r.id===i));this.agentId=n(e)?e:this.server.defaultAgent||this.server.agents[0]?.id||e||"",await this.loadConversation()}catch(e){this.activated=!1,this.renderLog(),this.showError(null,e)}this.renderSubtitle(),this.updatePageChoice(),this.emit("dewee:ready",{agent:this.agentId,config:this.server})}}async switchAgent(e){e!==this.agentId&&(this.stop(),this.agentId=e,this.renderSubtitle(),await this.loadConversation())}async loadConversation(){let e=this.config.persist!==!1,n=e?_.get(this.convKey()):null;if(this.conversationId=n||We(),e&&!n&&_.set(this.convKey(),this.conversationId),this.messages=[],this.renderLog(),!!n)try{let i=await this.client().history(this.agentId,this.conversationId);this.messages=$t(i.map(r=>({...r,status:"done"}))),this.renderLog()}catch{}}renderLog(){let e=this.els.log;U(e),e.replaceChildren(),this.messages.length||e.appendChild(this.renderWelcome());for(let n of this.messages)e.appendChild(this.renderMessage(n));e.scrollTop=e.scrollHeight}renderWelcome(){let e=this.config,n=this.strings,i=document.createElement("div");i.className="welcome";let r=document.createElement("h2");r.textContent=e.greeting||n.greeting;let o=document.createElement("p");if(o.textContent=e.intro||n.greetingBody,i.append(r,o),e.suggestions?.length){let c=document.createElement("div");c.className="suggestions";for(let a of e.suggestions){let d=document.createElement("button");d.className="chip",d.type="button",d.textContent=a,d.addEventListener("click",()=>this.send(a)),c.appendChild(d)}i.appendChild(c)}return i}pushMessage(e){this.messages.length||this.els.log.replaceChildren(),this.messages.push(e),this.els.log.appendChild(this.renderMessage(e)),this.scrollToBottom(!0)}renderMessage(e){let n=document.createElement("div");n.className=`msg ${e.role}${e.status==="error"?" error":""}`,n.hidden=!!e.hidden;let i=document.createElement("div");i.className="bubble",n.appendChild(i);let r=document.createElement("div");r.className="trace";let o=document.createElement("div");o.className=e.role==="assistant"?"md":"";let c=document.createElement("div");return c.className="actions",c.hidden=!0,e.role==="assistant"&&i.appendChild(r),i.appendChild(o),e.role==="assistant"&&i.appendChild(c),e.view={root:n,trace:r,md:o,tools:new Map,actions:c},this.updateMessage(e),n}updateMessage(e){let n=e.view;if(!n)return;let i=this.config;if(e.role==="user"){n.md.textContent=e.content,n.root.classList.toggle("refused",!!e.refusal);let a=n.root.querySelector(".refusal");e.refusal&&!a&&(a=document.createElement("div"),a.className="refusal",n.root.appendChild(a)),a&&e.refusal?a.textContent=`\u26A0\uFE0F ${e.refusal}`:a?.remove();return}if(n.root.classList.toggle("error",e.status==="error"),i.showReasoning!==!1&&e.thinking){n.thinking||(n.thinking=document.createElement("details"),n.thinking.className="thinking",n.thinking.innerHTML='<summary></summary><div class="thinking-body"></div>',n.trace.prepend(n.thinking));let a=e.status==="streaming"&&!e.thinkingMs,d=a?this.strings.thinking:e.thinkingMs?this.strings.thoughtFor(Math.max(1,Math.round(e.thinkingMs/1e3))):this.strings.reasoning,l=n.thinking.querySelector("summary");l.innerHTML=`${a?'<span class="spin"></span>':C.brain}<span></span>${C.down.replace("<svg",'<svg class="chev"')}`,l.querySelector("span:not(.spin)").textContent=d,n.thinking.querySelector(".thinking-body").textContent=e.thinking}else n.thinking&&(n.thinking.remove(),n.thinking=void 0);if(i.showToolCalls!==!1)for(let a of e.toolCalls??[])this.renderTool(n,a);else n.tools.forEach(a=>a.remove()),n.tools.clear();n.trace.hidden=!n.trace.childElementCount;let r=this.actionRegistry().size||e.actions?Ce(e.content):e.content,o=e.status==="streaming"&&!r;n.md.hidden=!o&&!r&&!!e.actions?.length;let c=JSON.stringify([r,o,e.status==="streaming",i.endpoint,i.imageOrigins,this.strings.thinking]);n.mdKey!==c&&(n.mdKey=c,U(n.md),o?n.md.innerHTML=`<span class="typing" aria-label="${this.strings.thinking}"><i></i><i></i><i></i></span>`:n.md.replaceChildren(R(document,r,{imageOrigins:Array.isArray(i.imageOrigins)?i.imageOrigins:[],imageProxy:(a,d)=>this.client().imageUrl(a,d),deferImages:e.status==="streaming"})),n.md.classList.toggle("cursor",e.status==="streaming")),this.renderActions(n,e.actions??[])}renderActions(e,n){e.actions.hidden=!n.length,e.actions.replaceChildren(...n.map(i=>{let r=document.createElement("div");r.className="action",r.dataset.status=i.status;let o=i.status==="running"||i.status==="awaiting-confirmation";r.innerHTML=`${o?'<span class="spin"></span>':C.action}<span class="action-name"></span><span class="action-state"></span>`,r.querySelector(".action-name").textContent=i.name||"?",r.querySelector(".action-state").textContent=this.strings.actionStatus[i.status];let c=[i.args&&Object.keys(i.args).length?JSON.stringify(i.args):"",i.error??""].filter(Boolean).join(`
341
+ `);return c&&(r.title=c),r}))}renderTool(e,n){let i=e.tools.get(n.id);i||(i=document.createElement("details"),i.className="tool",i.innerHTML=`<summary><span class="lead"></span><span class="tool-name"></span><span class="tool-state"></span>${C.down.replace("<svg",'<svg class="chev"')}</summary><div class="tool-body"></div>`,e.tools.set(n.id,i),e.trace.appendChild(i)),i.dataset.status=n.status,i.querySelector(".lead").innerHTML=n.status==="running"?'<span class="spin"></span>':C.tool;let r=i.querySelector(".tool-name");r.textContent=Nt(n.name),r.setAttribute("title",n.name),i.querySelector(".tool-state").textContent=n.status==="running"?this.strings.toolRunning:n.status==="error"?this.strings.toolError:this.strings.toolDone;let o=i.querySelector(".tool-body");o.replaceChildren();let c=(a,d)=>{if(d==null||d==="")return;let l=document.createElement("div");l.className="label",l.textContent=a;let p=document.createElement("pre");p.textContent=typeof d=="string"?zt(d):JSON.stringify(d,null,2),o.append(l,p)};c(this.strings.args,n.arguments),c(this.strings.result,n.result)}onStreamEvent(e,n){switch(n.type){case"start":n.actionsHash&&(e.actionsHash=n.actionsHash,e.ackVisitor=this.client().visitorId()??void 0),n.conversationId&&n.conversationId!==this.conversationId&&(this.conversationId=n.conversationId,this.config.persist!==!1&&_.set(this.convKey(),n.conversationId));break;case"thinking":e.thinking=(e.thinking||"")+n.text;break;case"delta":this.finishThinking(e),e.content+=n.text;break;case"tool_call":this.finishThinking(e),(e.toolCalls??(e.toolCalls=[])).push({id:n.id,name:n.name,arguments:n.arguments,status:"running"});break;case"tool_result":{let i=e.toolCalls?.find(r=>r.id===n.id)??(e.toolCalls??(e.toolCalls=[]))[e.toolCalls.push({id:n.id,name:n.name,status:"running"})-1];i.status=n.isError?"error":"done",i.result=n.result,i.isError=n.isError;break}case"done":this.finishThinking(e),n.content&&n.content.length>=e.content.length&&(e.content=n.content),e.status="done";break;case"error":e.status="error",this.showError(e,new E(n.message,500,n.code,n.remediation,n.retryAfterMs));break}this.scheduleUpdate(e)}scheduleUpdate(e){this.pendingFrame||(this.pendingFrame=requestAnimationFrame(()=>{this.pendingFrame=0,this.updateMessage(e),this.following&&this.scrollToBottom(!0)}))}finishThinking(e){e.thinking&&!e.thinkingMs&&e.startedAt&&(e.thinkingMs=Date.now()-e.startedAt)}nearBottom(){let e=this.els.log;return e.scrollHeight-e.scrollTop-e.clientHeight<96}scrollToBottom(e=!1){let n=this.els.log;(e||this.nearBottom())&&(n.scrollTop=n.scrollHeight,this.following=!0)}showError(e,n){let{code:i,remediation:r,retryAfterMs:o}=n,a=(Y(i)?this.strings.identityErrors[i]:G(i)?this.strings.admissionErrors[i]:ye(i)?this.strings.linkErrors[i]:"")||n.message||this.strings.errorGeneric;if(this.emit("dewee:error",{message:a,code:i,...r&&{remediation:r},...o&&{retryAfterMs:o}}),i==="RATE_LIMITED"&&this.startCooldown(o),e&&G(i)&&this.refuseInline(e,i,a))return;if(e){e.content=e.content?`${e.content}
342
+
343
+ > \u26A0\uFE0F ${a}`:`\u26A0\uFE0F ${a}`,e.status="error",this.updateMessage(e);return}let d=document.createElement("div");d.className="msg error",d.innerHTML='<div class="bubble"></div>',d.firstElementChild.textContent=`\u26A0\uFE0F ${a}`,this.els.log.appendChild(d)}refuseInline(e,n,i){let r=this.messages.indexOf(e),o=r>0?this.messages[r-1]:void 0;return o?.role!=="user"||o.hidden||(this.els.input.value.trim()||(this.els.input.value=o.content,this.autosize()),n!=="POLICY_DENIED"||e.content)?!1:(e.status="error",e.hidden=!0,e.view&&(e.view.root.hidden=!0),o.refusal=i,this.updateMessage(o),!0)}async challenge(e){await Ht();let n=document.createElement("div");n.slot="challenge",this.appendChild(n);try{return await new Promise((i,r)=>{window.turnstile.render(n,{sitekey:e,appearance:"interaction-only",theme:this.getAttribute("data-theme")==="dark"?"dark":"light",callback:i,"error-callback":()=>r(new E("Verification failed",403,"turnstile_failed"))})})}finally{n.remove()}}};function $t(t){return t.forEach((s,e)=>{if(s.role==="user"){s.content=ie(s.content),Z(s.content)&&(s.hidden=!0);return}if(!s.content.includes("```dewee-action"))return;let{calls:n}=X(s.content);if(!n.length)return;let i=t[e+1],r=i?.role==="user"?ie(i.content):"",o=Z(r)?Se(r):[];s.actions=n.map(c=>{let a=o.find(l=>l.id===c.id),d=a?a.status==="ok"?"done":a.status:"error";return{id:c.id,name:c.name,args:c.ok?c.args:void 0,status:d,error:a?a.error:"Not run"}})}),t}var jt={telegram:"Telegram",discord:"Discord",zalo:"Zalo",slack:"Slack",whatsapp:"WhatsApp",messenger:"Messenger",feishu:"Feishu",line:"LINE"};function Bt(t){let s=t.toLowerCase().split(/[_-]/)[0];return jt[s]??(t?t.charAt(0).toUpperCase()+t.slice(1):"chat")}function ge(t,s){try{return JSON.parse(t)}catch{return s}}function zt(t){let s=t.trim();if(!/^[[{]/.test(s))return t;try{return JSON.stringify(JSON.parse(s),null,2)}catch{return t}}function fe(t="dewee-chat"){typeof window>"u"||!window.customElements||customElements.get(t)||customElements.define(t,class extends D{})}function qt(t={},s){fe();let e=document.createElement("dewee-chat");return e.configure(t),((typeof s=="string"?document.querySelector(s):s)??document.body).appendChild(e),e}fe();var Ut=document.currentScript,K=Ut?.dataset;if(K&&K.endpoint&&K.autoMount!=="false"){let t=()=>{let s=document.createElement("dewee-chat");for(let[e,n]of Object.entries(K))e==="autoMount"||n===void 0||s.setAttribute(e.replace(/[A-Z]/g,i=>"-"+i.toLowerCase()),n);document.body.appendChild(s)};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",t):t()}window.DeweeWebchat=me;})();