dewee-webchat 0.3.0 → 0.4.1-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.
- package/README.md +237 -22
- package/dist/{chunk-ZTVGWFXL.js → chunk-7WT3JK64.js} +580 -42
- package/dist/{chunk-W6A4HVFB.js → chunk-USXVB3AC.js} +52 -7
- package/dist/dewee-webchat.js +36 -29
- package/dist/handler-DunrbnSD.d.ts +307 -0
- package/dist/index.d.ts +91 -7
- package/dist/index.js +2 -2
- package/dist/protocol-CLbGE9Ns.d.ts +170 -0
- package/dist/react.d.ts +1 -1
- package/dist/react.js +2 -2
- package/dist/server-identity.d.ts +6 -0
- package/dist/server-identity.js +6 -0
- package/dist/server.d.ts +33 -75
- package/dist/server.js +1507 -41
- package/dist/vue.d.ts +3 -3
- package/dist/vue.js +2 -2
- package/package.json +13 -1
- package/dist/protocol-B72Ry-fY.d.ts +0 -92
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
// src/protocol.ts
|
|
2
|
+
var IDENTITY_ERROR_CODES = [
|
|
3
|
+
"IDENTITY_REQUIRED",
|
|
4
|
+
"IDENTITY_LINK_REQUIRED",
|
|
5
|
+
"IDENTITY_CONFLICT",
|
|
6
|
+
"LINK_EXPIRED",
|
|
7
|
+
"LINK_REVOKED",
|
|
8
|
+
"PERMISSION_DENIED",
|
|
9
|
+
"SOURCE_UNAVAILABLE"
|
|
10
|
+
];
|
|
11
|
+
function isIdentityErrorCode(code) {
|
|
12
|
+
return typeof code === "string" && IDENTITY_ERROR_CODES.includes(code);
|
|
13
|
+
}
|
|
14
|
+
var ADMISSION_ERROR_CODES = ["POLICY_DENIED", "RATE_LIMITED", "CHALLENGE_REQUIRED"];
|
|
15
|
+
function isAdmissionErrorCode(code) {
|
|
16
|
+
return typeof code === "string" && ADMISSION_ERROR_CODES.includes(code);
|
|
17
|
+
}
|
|
18
|
+
var LINK_ERROR_CODES = ["idempotency_key_reused", "link_in_progress", "linking_unavailable"];
|
|
19
|
+
function isLinkErrorCode(code) {
|
|
20
|
+
return typeof code === "string" && LINK_ERROR_CODES.includes(code);
|
|
21
|
+
}
|
|
22
|
+
var HEADER_GATEWAY_URL = "x-dewee-gateway-url";
|
|
23
|
+
var HEADER_GATEWAY_TOKEN = "x-dewee-gateway-token";
|
|
24
|
+
var VERSION = "0.4.1-beta.1";
|
|
25
|
+
|
|
1
26
|
// src/actions/page-block.ts
|
|
2
27
|
var ACTION_NAME_RE = /^[a-z][a-z0-9_.-]{0,63}$/;
|
|
3
28
|
var SENSITIVITIES = ["read", "navigate", "mutate", "destructive"];
|
|
@@ -90,12 +115,34 @@ function stripPageBlock(content) {
|
|
|
90
115
|
return content.slice(end + PAGE_BLOCK_CLOSE.length + 1).replace(/^\n+/, "");
|
|
91
116
|
}
|
|
92
117
|
|
|
93
|
-
// src/
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
118
|
+
// src/job-access.ts
|
|
119
|
+
function parseJobAccessLaunch(raw) {
|
|
120
|
+
const fail = () => {
|
|
121
|
+
throw new Error("Job access is unavailable");
|
|
122
|
+
};
|
|
123
|
+
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return fail();
|
|
124
|
+
const data = raw;
|
|
125
|
+
if (typeof data.bootstrap_url !== "string" || typeof data.launch_token !== "string" || !/^[A-Za-z0-9_.-]{16,16384}$/.test(data.launch_token) || typeof data.expires_at !== "string") return fail();
|
|
126
|
+
let url;
|
|
127
|
+
try {
|
|
128
|
+
url = new URL(data.bootstrap_url);
|
|
129
|
+
} catch {
|
|
130
|
+
return fail();
|
|
131
|
+
}
|
|
132
|
+
if (url.protocol !== "https:" || url.username || url.password || url.search || url.hash || url.pathname !== "/identity/job-access/launch" || url.href !== data.bootstrap_url) return fail();
|
|
133
|
+
const deadline = Date.parse(data.expires_at);
|
|
134
|
+
if (!Number.isFinite(deadline) || deadline <= Date.now() || deadline > Date.now() + 6e4) return fail();
|
|
135
|
+
return { bootstrap_url: url.href, launch_token: data.launch_token, expires_at: data.expires_at };
|
|
136
|
+
}
|
|
97
137
|
|
|
98
138
|
export {
|
|
139
|
+
isIdentityErrorCode,
|
|
140
|
+
ADMISSION_ERROR_CODES,
|
|
141
|
+
isAdmissionErrorCode,
|
|
142
|
+
isLinkErrorCode,
|
|
143
|
+
HEADER_GATEWAY_URL,
|
|
144
|
+
HEADER_GATEWAY_TOKEN,
|
|
145
|
+
VERSION,
|
|
99
146
|
ACTION_NAME_RE,
|
|
100
147
|
SENSITIVITIES,
|
|
101
148
|
ACTION_LIMITS,
|
|
@@ -105,7 +152,5 @@ export {
|
|
|
105
152
|
hashManifest,
|
|
106
153
|
buildPageBlock,
|
|
107
154
|
stripPageBlock,
|
|
108
|
-
|
|
109
|
-
HEADER_GATEWAY_TOKEN,
|
|
110
|
-
VERSION
|
|
155
|
+
parseJobAccessLaunch
|
|
111
156
|
};
|
package/dist/dewee-webchat.js
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
"use strict";(()=>{var
|
|
1
|
+
"use strict";(()=>{var te=Object.defineProperty;var Te=(i,s,e)=>s in i?te(i,s,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[s]=e;var Ie=(i,s)=>{for(var e in s)te(i,e,{get:s[e],enumerable:!0})};var u=(i,s,e)=>Te(i,typeof s!="symbol"?s+"":s,e);var ee={};Ie(ee,{ApiClient:()=>I,ApiError:()=>x,DeweeChatElement:()=>M,RESERVED_HEADERS:()=>Q,defineDeweeChat:()=>X,mount:()=>it,renderMarkdown:()=>L});var Le=["IDENTITY_REQUIRED","IDENTITY_LINK_REQUIRED","IDENTITY_CONFLICT","LINK_EXPIRED","LINK_REVOKED","PERMISSION_DENIED","SOURCE_UNAVAILABLE"];function j(i){return typeof i=="string"&&Le.includes(i)}var Re=["POLICY_DENIED","RATE_LIMITED","CHALLENGE_REQUIRED"];function B(i){return typeof i=="string"&&Re.includes(i)}var _e=["idempotency_key_reused","link_in_progress","linking_unavailable"];function ne(i){return typeof i=="string"&&_e.includes(i)}var z="x-dewee-gateway-url",J="x-dewee-gateway-token";var ie="dewee-action",se="dewee-action-result",P={maxCalls:8,maxBlockBytes:8192},Me=/^[A-Za-z0-9_.:-]{1,64}$/,Pe=/^\s{0,3}```\s*$/,oe=i=>new RegExp("^\\s{0,3}```"+i.replace(/[.-]/g,"\\$&")+"\\s*$"),re=oe(ie),ae=oe(se);function q(i,s){let e=[];for(let t=0;t<i.length;t++){if(!s.test(i[t]))continue;let n=t,o=[],r=!1;for(t++;t<i.length;t++){if(Pe.test(i[t])){r=!0;break}o.push(i[t])}e.push({start:n,end:Math.min(t,i.length-1),body:o,closed:r})}return e}var ce=(i,s)=>{let e=new Set;for(let t of s)for(let n=t.start;n<=t.end;n++)e.add(n);return i.filter((t,n)=>!e.has(n)).join(`
|
|
2
2
|
`).replace(/\n{3,}/g,`
|
|
3
3
|
|
|
4
|
-
`).trim()};function
|
|
4
|
+
`).trim()};function K(i){let s=i.replace(/\r\n?/g,`
|
|
5
5
|
`).split(`
|
|
6
|
-
`),
|
|
7
|
-
`),
|
|
6
|
+
`),e=q(s,re),t=[],n=new Set;return e.forEach((o,r)=>{let a=`call-${r+1}`,l=o.body.join(`
|
|
7
|
+
`),c=(f,m=a,w="")=>t.push({ok:!1,id:m,name:w,error:f});if(r>=P.maxCalls)return c(`Too many action calls in one reply (max ${P.maxCalls})`);if(!o.closed)return c("Unclosed dewee-action block");if(new TextEncoder().encode(l).length>P.maxBlockBytes)return c(`Action block exceeds ${P.maxBlockBytes} bytes`);let d;try{d=JSON.parse(l)}catch{return c("Action block is not valid JSON")}if(typeof d!="object"||d===null||Array.isArray(d))return c("Action block must be a JSON object");let h=typeof d.id=="string"&&Me.test(d.id)?d.id:a,p=typeof d.name=="string"?d.name.slice(0,64):"";if(n.has(h))return c(`Duplicate action call id "${h}"`,`${h}-${r+1}`,p);if(n.add(h),!p)return c("Action name is required",h);let g=d.args??{};if(typeof g!="object"||g===null||Array.isArray(g))return c("args must be a JSON object",h,p);t.push({ok:!0,id:h,name:p,args:g})}),{text:e.length?ce(s,e):i,calls:t}}function le(i){if(!i.includes("```"+ie))return i;let s=i.replace(/\r\n?/g,`
|
|
8
8
|
`).split(`
|
|
9
|
-
`);return
|
|
10
|
-
`,1)[0]??"")}function
|
|
9
|
+
`);return ce(s,q(s,re))}function V(i){return ae.test(i.trimStart().split(`
|
|
10
|
+
`,1)[0]??"")}function de(i){let s=i.replace(/\r\n?/g,`
|
|
11
11
|
`).split(`
|
|
12
|
-
`),
|
|
13
|
-
`));
|
|
14
|
-
`+JSON.stringify(i)+"\n```";function
|
|
12
|
+
`),e=[];for(let t of q(s,ae))try{let n=JSON.parse(t.body.join(`
|
|
13
|
+
`));n&&typeof n.id=="string"&&["ok","denied","error"].includes(n.status)&&e.push(n)}catch{}return e}var _=i=>"```"+se+`
|
|
14
|
+
`+JSON.stringify(i)+"\n```";function he(i,s=4e3){let e=Math.max(64,Math.floor((s-16)/Math.max(1,i.length)));return i.map(n=>{let o={...n,result:U(n.result)};if(o.result===void 0&&delete o.result,_(o).length<=e)return _(o);let r=JSON.stringify(o.result??null),a=e-_({...o,result:{truncated:!0,preview:""}}).length-8,l=_({...o,result:{truncated:!0,preview:r.slice(0,Math.max(0,a))}});return l.length<=e?l:_({id:n.id,name:n.name.slice(0,64),status:n.status,result:{truncated:!0}})}).join(`
|
|
15
15
|
|
|
16
|
-
`).slice(0,s)}function
|
|
17
|
-
`+
|
|
16
|
+
`).slice(0,s)}function U(i){if(i!==void 0)try{let s=JSON.stringify(i);return s===void 0?null:JSON.parse(s)}catch{return"[unserializable result]"}}var Y=i=>i===null?"null":Array.isArray(i)?"array":typeof i=="number"?Number.isInteger(i)?"integer":"number":typeof i,Ne=(i,s)=>{let e=Y(i);return e===s||s==="number"&&e==="integer"};function N(i,s,e="args",t=0){if(!s||typeof s!="object")return null;if(t>32)return`${e}: schema is nested too deeply`;let n=s;if(n.type!==void 0){let o=Array.isArray(n.type)?n.type:[n.type];if(!o.some(r=>Ne(i,r)))return`${e}: expected ${o.join(" or ")}, got ${Y(i)}`}if(Array.isArray(n.enum)&&!n.enum.some(o=>pe(o,i)))return`${e}: must be one of ${n.enum.map(o=>JSON.stringify(o)).join(", ")}`;if("const"in n&&!pe(n.const,i))return`${e}: must equal ${JSON.stringify(n.const)}`;if(typeof i=="string"){if(typeof n.minLength=="number"&&i.length<n.minLength)return`${e}: shorter than ${n.minLength} characters`;if(typeof n.maxLength=="number"&&i.length>n.maxLength)return`${e}: longer than ${n.maxLength} characters`;if(typeof n.pattern=="string"){let o=null;try{o=new RegExp(n.pattern,"u")}catch{return`${e}: schema pattern is invalid`}if(!o.test(i))return`${e}: does not match ${n.pattern}`}}if(typeof i=="number"){if(typeof n.minimum=="number"&&i<n.minimum)return`${e}: must be >= ${n.minimum}`;if(typeof n.maximum=="number"&&i>n.maximum)return`${e}: must be <= ${n.maximum}`}if(Array.isArray(i)){if(typeof n.minItems=="number"&&i.length<n.minItems)return`${e}: needs at least ${n.minItems} items`;if(typeof n.maxItems=="number"&&i.length>n.maxItems)return`${e}: allows at most ${n.maxItems} items`;if(n.items&&typeof n.items=="object")for(let o=0;o<i.length;o++){let r=N(i[o],n.items,`${e}[${o}]`,t+1);if(r)return r}}if(Y(i)==="object"){let o=i,r=n.properties&&typeof n.properties=="object"?n.properties:{};for(let a of Array.isArray(n.required)?n.required:[])if(!(a in o))return`${e}.${a}: is required`;for(let[a,l]of Object.entries(o))if(Object.prototype.hasOwnProperty.call(r,a)){let c=N(l,r[a],`${e}.${a}`,t+1);if(c)return c}else if(n.additionalProperties===!1)return`${e}.${a}: is not allowed`}return null}function pe(i,s){return JSON.stringify(i)===JSON.stringify(s)}var ge=/^[a-z][a-z0-9_.-]{0,63}$/,F=["read","navigate","mutate","destructive"],S={maxActions:32,maxDescription:1e3,maxParametersBytes:4096,maxManifestBytes:16384,maxPageContextBytes:4096},De="[[dewee-page v1]]",ue="[[/dewee-page]]";function W(i){if(!i.startsWith(De))return i;let s=i.indexOf(`
|
|
17
|
+
`+ue);return s<0?i:i.slice(s+ue.length+1).replace(/^\n+/,"")}var Oe=i=>i==="mutate"||i==="destructive",D=class{constructor(){u(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 t of e)He(t);if(new Set([...this.map.keys(),...e.map(t=>t.name)]).size>S.maxActions)throw new TypeError(`dewee-webchat: at most ${S.maxActions} page actions`);for(let t of e)this.map.set(t.name,t)}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 He(i){let s=e=>{throw new TypeError(`dewee-webchat: invalid page action ${JSON.stringify(i?.name)}: ${e}`)};(!i||typeof i!="object")&&s("not an object"),(typeof i.name!="string"||!ge.test(i.name))&&s("name must match ^[a-z][a-z0-9_.-]{0,63}$"),(typeof i.description!="string"||i.description.length>S.maxDescription)&&s(`description must be a string up to ${S.maxDescription} chars`),F.includes(i.sensitivity)||s(`sensitivity must be one of ${F.join(", ")}`),typeof i.handler!="function"&&s("handler must be a function"),i.parameters!==void 0&&(typeof i.parameters!="object"||i.parameters===null||Array.isArray(i.parameters))&&s("parameters must be a JSON Schema object")}async function me(i,s){let e=l=>(s.onStatus?.("error"),{id:i.id,name:i.name,status:"error",error:l});if(!i.ok)return e(i.error);if(s.signal.aborted)return e("Cancelled");let t=s.registry.get(i.name);if(!t)return e(`Unknown action "${i.name}". Available: ${s.registry.names().join(", ")||"none"}`);let n=N(i.args,t.parameters??{type:"object"});if(n)return e(`Invalid arguments: ${n}`);if(Oe(t.sensitivity)){s.onStatus?.("awaiting-confirmation");let{handler:l,...c}=t,d=!1;try{d=await fe(Promise.resolve(s.confirm({...c,callId:i.id},i.args)),s.signal)===!0}catch{d=!1}if(!d||s.signal.aborted)return s.onStatus?.("denied"),{id:i.id,name:i.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 l=await fe(Promise.resolve().then(()=>t.handler(i.args,{callId:i.id,conversationId:s.conversationId,agent:s.agent,signal:o.signal})),o.signal);return s.onStatus?.("done"),{id:i.id,name:i.name,status:"ok",result:U(l)??null}}catch(l){return e(o.signal.aborted?s.signal.aborted?"Cancelled":"Timed out":String(l?.message??l).slice(0,500)||"Action failed")}finally{clearTimeout(a),s.signal.removeEventListener("abort",r)}}function fe(i,s){return s.aborted?Promise.reject(new Error("aborted")):new Promise((e,t)=>{let n=()=>t(new Error("aborted"));s.addEventListener("abort",n,{once:!0}),i.then(e,t).finally(()=>s.removeEventListener("abort",n))})}function O(i){let s=()=>{throw new Error("Job access is unavailable")};if(!i||typeof i!="object"||Array.isArray(i))return s();let e=i;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 t;try{t=new URL(e.bootstrap_url)}catch{return s()}if(t.protocol!=="https:"||t.username||t.password||t.search||t.hash||t.pathname!=="/identity/job-access/launch"||t.href!==e.bootstrap_url)return s();let n=Date.parse(e.expires_at);return!Number.isFinite(n)||n<=Date.now()||n>Date.now()+6e4?s():{bootstrap_url:t.href,launch_token:e.launch_token,expires_at:e.expires_at}}var $e=new Set(["LINK_EXPIRED","LINK_REVOKED"]),je=6e4,Q=["content-type","authorization",z,J],x=class extends Error{constructor(e,t,n,o,r){super(e);u(this,"status",t);u(this,"code",n);u(this,"remediation",o);u(this,"retryAfterMs",r)}};function Be(i,s){if(typeof i=="number"&&Number.isFinite(i)&&i>0)return i;let e=Number(s.headers.get("retry-after"));return Number.isFinite(e)&&e>0?e*1e3:void 0}var be=i=>({get(s){try{return i().getItem(s)}catch{return null}},set(s,e){try{i().setItem(s,e)}catch{}},del(s){try{i().removeItem(s)}catch{}}}),G=be(()=>localStorage),T=be(()=>sessionStorage),I=class{constructor(s){u(this,"o",s);u(this,"session",null);u(this,"config",null);u(this,"sessionPromise",null);u(this,"refreshAt",new WeakMap)}url(s,e){let t=this.o.endpoint.replace(/\/+$/,""),n=e?"?"+new URLSearchParams(e).toString():"";return`${t}/${s}${n}`}get storageKey(){return`dewee-webchat:session:${this.o.endpoint}`}get reuseKey(){return`dewee-webchat:reuse:${this.o.endpoint}`}reuseHint(){return T.get(this.reuseKey)}request(s,e){return(this.o.fetch??globalThis.fetch)(s,e)}async headers(s=!1){let e={},t=typeof this.o.headers=="function"?await this.o.headers():this.o.headers;for(let[n,o]of Object.entries(t??{}))typeof o=="string"&&!Q.includes(n.toLowerCase())&&(e[n.toLowerCase()]=o);if(e["content-type"]="application/json",this.o.gatewayUrl&&this.o.gatewayToken&&(e[z]=this.o.gatewayUrl,e[J]=this.o.gatewayToken),s){let n=this.session&&this.fresh(this.session)?this.session:await this.ensureSession();e.authorization=`Bearer ${n.token}`}return e}async parse(s){let e=await s.json().catch(()=>({}));if(!s.ok){let t=e?.error?.remediation,n=t&&typeof t.action=="string"&&typeof t.audience=="string"?{action:t.action,audience:t.audience}:void 0;throw new x(e?.error?.message||`HTTP ${s.status}`,s.status,e?.error?.code,n,Be(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,t=e?s.obtainedAt+s.expiresIn:s.expiresAt,n=e?s.expiresIn:s.obtainedAt?s.expiresAt-s.obtainedAt:1/0,o=Math.min(864e5,Math.max(3e4,n*.1));return t-Date.now()>o}scheduleRefresh(s,e){let t=typeof s.expiresIn=="number"&&s.expiresIn>0?s.expiresIn:s.expiresAt-e;this.refreshAt.set(s,e+t-Math.min(je,t/2))}stored(){let s=G.get(this.storageKey);if(!s)return null;try{let e=JSON.parse(s);return e.verified?null:e}catch{return 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={},t=this.session&&!this.session.verified?this.session:this.stored();if(t?.token&&(e.token=t.token),s.identity){let c=this.session?.verified?this.session.reuseHint:T.get(this.reuseKey);c&&(e.reuseHint=c)}let n=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 x("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 n()}catch(c){if(!(s.turnstileSiteKey&&!e.turnstileToken&&c instanceof x&&c.code==="turnstile_failed"))throw c;await o(),r=await n()}}catch(c){throw c instanceof x&&c.status===401&&T.del(this.reuseKey),c}let a=Date.now(),l={...r,obtainedAt:a};if(this.session=l,l.verified)this.scheduleRefresh(l,a),typeof l.reuseHint=="string"&&l.reuseHint!==""?T.set(this.reuseKey,l.reuseHint):T.del(this.reuseKey);else{T.del(this.reuseKey);let{reuseHint:c,...d}=l;G.set(this.storageKey,JSON.stringify(d))}return l}forgetSession(){if(this.session?.verified){T.del(this.reuseKey),this.session=null;return}this.session=null,G.del(this.storageKey)}async renewSession(){return this.session=null,this.ensureSession()}async jobAccess(s){try{if(!(await this.ensureSession()).verified)throw new x("Sign in to open job access",401,"IDENTITY_REQUIRED");if(s.aborted)throw new x("Job access was cancelled",0,"job_access_unavailable");let t=await this.request(this.url("job-access"),{method:"POST",headers:await this.headers(!0),body:"{}",signal:s,redirect:"error"});return O(await this.parse(t))}catch(e){let t=e instanceof x&&typeof e.code=="string"&&["IDENTITY_REQUIRED","LINK_EXPIRED","LINK_REVOKED","PERMISSION_DENIED","SOURCE_UNAVAILABLE"].includes(e.code)?e.code:"job_access_unavailable";throw new x("Job access is unavailable. Sign in again or retry.",e instanceof x?e.status:0,t)}}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 t=await this.signedInRequest(async()=>this.request(this.url("history",{agent:s,conversationId:e}),{headers:await this.headers(!0)}));return(await this.parse(t)).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,t){await this.ensureSession();let n=await this.request(this.url("chat"),{method:"POST",headers:await this.headers(!0),body:JSON.stringify(s),signal:t});n.status===401&&(this.forgetSession(),await this.ensureSession(),n=await this.request(this.url("chat"),{method:"POST",headers:await this.headers(!0),body:JSON.stringify(s),signal:t})),(!n.ok||!n.body)&&await this.parse(n);let o=n.body.pipeThrough(new TextDecoderStream).getReader(),r="",a=!1;for(;;){let{done:l,value:c}=await o.read();if(l)break;r+=c;let d;for(;(d=r.indexOf(`
|
|
18
18
|
|
|
19
|
-
`))>=0;){let
|
|
20
|
-
`).filter(
|
|
21
|
-
`);if(g)try{t(
|
|
22
|
-
<div class="confirm" role="alertdialog" aria-modal="true" aria-labelledby="${
|
|
23
|
-
<h3 id="${
|
|
24
|
-
<div id="${
|
|
19
|
+
`))>=0;){let h=r.slice(0,d);r=r.slice(d+2);let p=h.split(`
|
|
20
|
+
`).filter(f=>f.startsWith("data:")).map(f=>f.slice(5).trimStart()).join(`
|
|
21
|
+
`);if(!p)continue;let g;try{g=JSON.parse(p)}catch{continue}g.type==="error"&&g.code&&$e.has(g.code)&&(a=!0);try{e(g)}catch{}}}a&&this.session?.verified&&(this.forgetSession(),await this.ensureSession().catch(()=>{}))}};var E=class extends Error{constructor(e){super("Job access could not be opened");u(this,"code",e)}};async function we(i,s){let e=`dewee-job-access-${crypto.randomUUID()}`,t;try{t=window.open("about:blank",e,"popup,width=720,height=800")}catch{throw new E("popup_blocked")}if(!t)throw new E("popup_blocked");let n=new AbortController,o=()=>n.abort(),r,a=new Promise((y,v)=>{r=()=>v(new E(t.closed?"popup_closed":"job_access_unavailable"))});n.signal.addEventListener("abort",r,{once:!0}),s?.addEventListener("abort",o,{once:!0});let l=setTimeout(o,3e4),c=!1,d,h,p=new Promise((y,v)=>{d=y,h=()=>v(new E("job_access_unavailable"))}),g=setInterval(()=>{if(t.closed){o();return}if(c)try{t.location.href!=="about:blank"&&d()}catch{d()}},200);window.addEventListener("pagehide",o,{once:!0});let f,m,w,k=y=>{y.disposition==="enforce"&&(y.effectiveDirective==="form-action"||y.violatedDirective==="form-action")&&h()};try{t.opener=null,s?.aborted&&o();let y=O(await Promise.race([i(n.signal),a]));if(t.closed)throw new E("popup_closed");if(n.signal.aborted)throw new E("job_access_unavailable");w=t.document;let v=w.createElement("meta");v.name="referrer",v.content="strict-origin",w.head.append(v),f=w.createElement("form"),f.method="POST",f.action=y.bootstrap_url,f.target="_self",f.hidden=!0,m=w.createElement("input"),m.type="hidden",m.name="launch_token",m.value=y.launch_token,f.append(m),w.body.append(f),w.addEventListener("securitypolicyviolation",k),HTMLFormElement.prototype.submit.call(f),c=!0,m.value="",y.launch_token="",f.remove(),await Promise.race([p,a])}catch(y){let v=t.closed;try{t.close()}catch{}throw v?new E("popup_closed"):(y instanceof E,y)}finally{m&&(m.value=""),f?.remove(),w?.removeEventListener("securitypolicyviolation",k),clearTimeout(l),clearInterval(g),window.removeEventListener("pagehide",o),s?.removeEventListener("abort",o),n.signal.removeEventListener("abort",r),n.abort()}}var ze=0;function ye(i,s,e,t,n){let o=`dw-confirm-${++ze}`,r=i.getRootNode(),a=r.activeElement,l=document.createElement("div");l.className="confirm-backdrop",l.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">
|
|
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=w=>c.querySelector(w);l("h3").textContent=s.confirmTitle,l("code").textContent=t.name;let d=l(".sens");if(d.textContent=t.sensitivity,d.dataset.level=t.sensitivity,l(".confirm-text").textContent=t.description,t.sensitivity==="destructive"){let w=l(".confirm-warn");w.hidden=!1,w.textContent=s.confirmDestructive}let g=JSON.stringify(n,null,2),p=l(".confirm-args");g&&g!=="{}"?p.textContent=g:p.remove();let u=l(".deny"),m=l(".allow");return u.textContent=s.deny,m.textContent=s.allow,t.sensitivity==="destructive"&&m.classList.add("danger"),new Promise(w=>{let b=!1,y=A=>{b||(b=!0,e?.removeEventListener("abort",M),c.remove(),a?.focus?.(),w(A))},M=()=>y(!1);if(e?.aborted)return y(!1);e?.addEventListener("abort",M,{once:!0}),u.addEventListener("click",()=>y(!1)),m.addEventListener("click",()=>y(!0)),c.addEventListener("keydown",A=>{A.key==="Escape"?(A.preventDefault(),A.stopPropagation(),y(!1)):A.key==="Tab"&&(A.preventDefault(),(o.activeElement===u?m:u).focus())}),i.appendChild(c),u.focus()})}var Tt={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:i=>`Thought for ${i}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:i=>`Stopped after ${i} automatic action rounds. Send a message to continue.`},Mt={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:i=>`\u0110\xE3 suy ngh\u0129 ${i} 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:i=>`\u0110\xE3 d\u1EEBng sau ${i} l\u01B0\u1EE3t thao t\xE1c t\u1EF1 \u0111\u1ED9ng. G\u1EEDi tin nh\u1EAFn \u0111\u1EC3 ti\u1EBFp t\u1EE5c.`};function U(i){return(i||(typeof document<"u"?document.documentElement.lang:"")||(typeof navigator<"u"?navigator.language:"")||"en").toLowerCase().startsWith("vi")?Mt:Tt}var x={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 f(i,s,t){let n=i.createElement(s);return t&&(n.className=t),n}function Rt(i){let s=i.trim();return/^(https?:|mailto:|tel:)/i.test(s)||/^[/#?]/.test(s)&&!s.startsWith("//")?s:null}var Pt=/(`+)([\s\S]*?[^`])\1(?!`)|\*\*([^*]+?)\*\*|__([^_]+?)__|~~([^~]+?)~~|\*([^*\s][^*]*?)\*|(?<![\w])_([^_\s][^_]*?)_(?![\w])|\[([^\]]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)|(https?:\/\/[^\s<>()]+[^\s<>().,;:!?'"])/;function k(i,s,t){let n=new RegExp(Pt.source,"g"),e=0;for(let r;r=n.exec(s);)if(r.index>e&&t.appendChild(i.createTextNode(s.slice(e,r.index))),e=r.index+r[0].length,r[2]!==void 0){let o=f(i,"code");o.textContent=r[2],t.appendChild(o)}else if(r[3]!==void 0||r[4]!==void 0){let o=f(i,"strong");k(i,r[3]??r[4],o),t.appendChild(o)}else if(r[5]!==void 0){let o=f(i,"del");k(i,r[5],o),t.appendChild(o)}else if(r[6]!==void 0||r[7]!==void 0){let o=f(i,"em");k(i,r[6]??r[7],o),t.appendChild(o)}else if(r[8]!==void 0){let o=Rt(r[9]);if(o){let a=f(i,"a");a.href=o,a.target="_blank",a.rel="noopener noreferrer nofollow",k(i,r[8],a),t.appendChild(a)}else t.appendChild(i.createTextNode(r[8]))}else if(r[10]!==void 0){let o=f(i,"a");o.href=r[10],o.target="_blank",o.rel="noopener noreferrer nofollow",o.textContent=r[10],t.appendChild(o)}e<s.length&&t.appendChild(i.createTextNode(s.slice(e)))}var pt=i=>/^\s*\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)*\|?\s*$/.test(i),gt=i=>i.trim().replace(/^\||\|$/g,"").split("|").map(s=>s.trim());function S(i,s){let t=i.createDocumentFragment(),n=s.replace(/\r\n?/g,`
|
|
34
|
+
</div>`;let c=m=>l.querySelector(m);c("h3").textContent=s.confirmTitle,c("code").textContent=e.name;let d=c(".sens");if(d.textContent=e.sensitivity,d.dataset.level=e.sensitivity,c(".confirm-text").textContent=e.description,e.sensitivity==="destructive"){let m=c(".confirm-warn");m.hidden=!1,m.textContent=s.confirmDestructive}let h=JSON.stringify(t,null,2),p=c(".confirm-args");h&&h!=="{}"?p.textContent=h:p.remove();let g=c(".deny"),f=c(".allow");return g.textContent=s.deny,f.textContent=s.allow,e.sensitivity==="destructive"&&f.classList.add("danger"),new Promise(m=>{let w=!1,k=v=>{w||(w=!0,n?.removeEventListener("abort",y),l.remove(),a?.focus?.(),m(v))},y=()=>k(!1);if(n?.aborted)return k(!1);n?.addEventListener("abort",y,{once:!0}),g.addEventListener("click",()=>k(!1)),f.addEventListener("click",()=>k(!0)),l.addEventListener("keydown",v=>{v.key==="Escape"?(v.preventDefault(),v.stopPropagation(),k(!1)):v.key==="Tab"&&(v.preventDefault(),(r.activeElement===g?f:g).focus())}),i.appendChild(l),g.focus()})}var Je={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:i=>`Thought for ${i}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:i=>`Stopped after ${i} 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:i=>`You can send again in ${i}s`,cooldownStart:i=>`Sending is paused. You can send again in ${i} second${i===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:i=>`Continue on ${i}`,linkExpires:i=>`The code expires in ${i} 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."},qe={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:i=>`\u0110\xE3 suy ngh\u0129 ${i} 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:i=>`\u0110\xE3 d\u1EEBng sau ${i} 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:i=>`B\u1EA1n c\xF3 th\u1EC3 g\u1EEDi l\u1EA1i sau ${i} gi\xE2y`,cooldownStart:i=>`T\u1EA1m d\u1EEBng g\u1EEDi tin nh\u1EAFn. B\u1EA1n c\xF3 th\u1EC3 g\u1EEDi l\u1EA1i sau ${i} 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:i=>`Ti\u1EBFp t\u1EE5c tr\xEAn ${i}`,linkExpires:i=>`M\xE3 h\u1EBFt h\u1EA1n sau ${i} 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 Z(i){return(i||(typeof document<"u"?document.documentElement.lang:"")||(typeof navigator<"u"?navigator.language:"")||"en").toLowerCase().startsWith("vi")?qe:Je}var A={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 b(i,s,e){let t=i.createElement(s);return e&&(t.className=e),t}function Ke(i){let s=i.trim();return/^(https?:|mailto:|tel:)/i.test(s)||/^[/#?]/.test(s)&&!s.startsWith("//")?s:null}var Ve=/(`+)([\s\S]*?[^`])\1(?!`)|\*\*([^*]+?)\*\*|__([^_]+?)__|~~([^~]+?)~~|\*([^*\s][^*]*?)\*|(?<![\w])_([^_\s][^_]*?)_(?![\w])|\[([^\]]+)\]\(([^)\s]+)(?:\s+"[^"]*")?\)|(https?:\/\/[^\s<>()]+[^\s<>().,;:!?'"])/;function C(i,s,e){let t=new RegExp(Ve.source,"g"),n=0;for(let o;o=t.exec(s);)if(o.index>n&&e.appendChild(i.createTextNode(s.slice(n,o.index))),n=o.index+o[0].length,o[2]!==void 0){let r=b(i,"code");r.textContent=o[2],e.appendChild(r)}else if(o[3]!==void 0||o[4]!==void 0){let r=b(i,"strong");C(i,o[3]??o[4],r),e.appendChild(r)}else if(o[5]!==void 0){let r=b(i,"del");C(i,o[5],r),e.appendChild(r)}else if(o[6]!==void 0||o[7]!==void 0){let r=b(i,"em");C(i,o[6]??o[7],r),e.appendChild(r)}else if(o[8]!==void 0){let r=Ke(o[9]);if(r){let a=b(i,"a");a.href=r,a.target="_blank",a.rel="noopener noreferrer nofollow",C(i,o[8],a),e.appendChild(a)}else e.appendChild(i.createTextNode(o[8]))}else if(o[10]!==void 0){let r=b(i,"a");r.href=o[10],r.target="_blank",r.rel="noopener noreferrer nofollow",r.textContent=o[10],e.appendChild(r)}n<s.length&&e.appendChild(i.createTextNode(s.slice(n)))}var ve=i=>/^\s*\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)*\|?\s*$/.test(i),xe=i=>i.trim().replace(/^\||\|$/g,"").split("|").map(s=>s.trim());function L(i,s){let e=i.createDocumentFragment(),t=s.replace(/\r\n?/g,`
|
|
35
35
|
`).split(`
|
|
36
|
-
`),
|
|
37
|
-
`),p.appendChild(
|
|
38
|
-
`))),
|
|
39
|
-
`)));continue}let
|
|
36
|
+
`),n=0;for(;n<t.length;){let o=t[n];if(!o.trim()){n++;continue}let r=o.match(/^\s*(```+|~~~+)\s*([\w+-]*)/);if(r){let h=[];for(n++;n<t.length&&!t[n].trim().startsWith(r[1]);)h.push(t[n++]);n++;let p=b(i,"pre"),g=b(i,"code");r[2]&&(g.dataset.lang=r[2]),g.textContent=h.join(`
|
|
37
|
+
`),p.appendChild(g),e.appendChild(p);continue}let a=o.match(/^(#{1,6})\s+(.*)$/);if(a){let h=`h${Math.min(6,a[1].length+2)}`,p=b(i,h);C(i,a[2],p),e.appendChild(p),n++;continue}if(/^\s*([-*_])(\s*\1){2,}\s*$/.test(o)){e.appendChild(b(i,"hr")),n++;continue}if(o.includes("|")&&n+1<t.length&&ve(t[n+1])){let h=b(i,"div","table"),p=b(i,"table"),g=b(i,"thead"),f=b(i,"tr");for(let w of xe(o)){let k=b(i,"th");C(i,w,k),f.appendChild(k)}g.appendChild(f),p.appendChild(g);let m=b(i,"tbody");for(n+=2;n<t.length&&t[n].includes("|")&&t[n].trim();){let w=b(i,"tr");for(let k of xe(t[n])){let y=b(i,"td");C(i,k,y),w.appendChild(y)}m.appendChild(w),n++}p.appendChild(m),h.appendChild(p),e.appendChild(h);continue}if(/^\s*>/.test(o)){let h=[];for(;n<t.length&&/^\s*>/.test(t[n]);)h.push(t[n++].replace(/^\s*>\s?/,""));let p=b(i,"blockquote");p.appendChild(L(i,h.join(`
|
|
38
|
+
`))),e.appendChild(p);continue}let l=o.match(/^(\s*)([-*+]|\d+[.)])\s+(.*)$/);if(l){let h=/\d/.test(l[2]),p=b(i,h?"ol":"ul");h&&parseInt(l[2],10)!==1&&p.setAttribute("start",String(parseInt(l[2],10)));let g=l[1].length;for(;n<t.length;){let f=t[n].match(/^(\s*)([-*+]|\d+[.)])\s+(.*)$/);if(!f||f[1].length<g||/\d/.test(f[2])!==h)break;if(f[1].length>g){let w=[];for(;n<t.length&&/^\s+/.test(t[n])&&t[n].match(/^(\s*)/)[1].length>g;)w.push(t[n++].slice(g+2));p.lastElementChild?.appendChild(L(i,w.join(`
|
|
39
|
+
`)));continue}let m=b(i,"li");C(i,f[3],m),p.appendChild(m),n++}e.appendChild(p);continue}let c=[];for(;n<t.length&&t[n].trim()&&!/^\s*(```|~~~|#{1,6}\s|>|([-*+]|\d+[.)])\s)/.test(t[n])&&!(t[n].includes("|")&&n+1<t.length&&ve(t[n+1]));)c.push(t[n++]);c.length||c.push(t[n++]);let d=b(i,"p");c.forEach((h,p)=>{p&&d.appendChild(b(i,"br")),C(i,h,d)}),e.appendChild(d)}return e}var H=class{constructor(s,e){u(this,"onTick",s);u(this,"onEnd",e);u(this,"until",0);u(this,"tick");u(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 ke=`
|
|
40
40
|
:host {
|
|
41
41
|
--dw-accent: #5446e8;
|
|
42
42
|
--dw-accent-contrast: #fff;
|
|
@@ -247,6 +247,10 @@ details > summary svg.ic { width: 14px; height: 14px; flex: none; }
|
|
|
247
247
|
.action[data-status="awaiting-confirmation"] .action-state { color: #b06f00; }
|
|
248
248
|
.action[data-status="denied"] .action-state, .action[data-status="error"] .action-state { color: #c2334f; }
|
|
249
249
|
.notice { margin: -6px 0 16px; font-size: 12px; color: var(--dw-muted); text-align: center; }
|
|
250
|
+
.msg.user.refused { flex-direction: column; align-items: flex-end; }
|
|
251
|
+
.refusal { margin-top: 6px; max-width: 86%; font-size: 12.5px; line-height: 1.45; color: #c2334f; text-align: right; }
|
|
252
|
+
.cooldown { margin: 0 2px 8px; font-size: 12px; color: var(--dw-muted); }
|
|
253
|
+
.sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
|
|
250
254
|
.confirm-backdrop {
|
|
251
255
|
position: absolute; inset: 0; z-index: 2; display: flex; align-items: flex-end; justify-content: center; padding: 12px;
|
|
252
256
|
background: color-mix(in srgb, var(--dw-fg) 28%, transparent); animation: rise .18s ease both;
|
|
@@ -301,8 +305,8 @@ textarea::placeholder { color: var(--dw-muted); }
|
|
|
301
305
|
.agent-select { font-size: 16px; max-width: 200px; }
|
|
302
306
|
}
|
|
303
307
|
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
|
|
304
|
-
`;var wt=["show-reasoning","show-tool-calls","allow-agent-switch","open","persist","hide-branding","launcher-avatar"],ut=["endpoint","agent","title","subtitle","greeting","intro","placeholder","suggestions","avatar","position","mode","theme","accent-color","locale","gateway-url","gateway-token","width","height","z-index",...wt],ft=i=>i.replace(/-([a-z])/g,(s,t)=>t.toUpperCase()),Lt=i=>i!==null&&!/^(false|0|off|no)$/i.test(i),mt=()=>{let i=crypto.getRandomValues(new Uint8Array(9));return Array.from(i,s=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"[s&63]).join("")},It=i=>i.replace(/^mcp_[^_]+(?:_[^_]+)*?__/,"").replace(/_/g," "),T={get(i){try{return localStorage.getItem(i)}catch{return null}},set(i,s){try{localStorage.setItem(i,s)}catch{}}},$t=null;function Ht(){return $t??($t=new Promise((i,s)=>{if(window.turnstile)return i();let t=document.createElement("script");t.src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit",t.async=!0,t.onload=()=>i(),t.onerror=()=>s(new Error("Could not load Turnstile")),document.head.appendChild(t)}))}var Nt=typeof HTMLElement>"u"?class{}:HTMLElement,P=class extends Nt{constructor(){super();h(this,"root");h(this,"overrides",{});h(this,"api",null);h(this,"apiKey","");h(this,"server",null);h(this,"agentId","");h(this,"conversationId","");h(this,"messages",[]);h(this,"running",null);h(this,"activated",!1);h(this,"strings",U());h(this,"mql",null);h(this,"registry",new $);h(this,"propActionNames",new Set);h(this,"hooks",{});h(this,"acks",new Map);h(this,"els");h(this,"onScheme",()=>this.applyTheme());h(this,"pendingFrame",0);h(this,"following",!0);this.root=this.attachShadow({mode:"open"})}static get observedAttributes(){return ut}get config(){let t={endpoint:"/api/dewee"};for(let n of ut){let e=this.getAttribute(n);e!==null&&(wt.includes(n)?t[ft(n)]=Lt(e):n==="suggestions"?t.suggestions=e.trim().startsWith("[")?Ot(e,[]):e.split("|").map(r=>r.trim()).filter(Boolean):n==="z-index"?t.zIndex=Number(e):t[ft(n)]=e)}return{...t,...this.overrides,...this.hooks}}configure(t){let{actions:n,confirm:e,getPageContext:r,headers:o,fetch:a,...c}=t,l=d=>Object.prototype.hasOwnProperty.call(t,d);l("actions")&&this.setPropActions(n??[]),l("confirm")&&(this.hooks.confirm=e),l("getPageContext")&&(this.hooks.getPageContext=r),l("headers")&&(this.hooks.headers=o),l("fetch")&&(this.hooks.fetch=a),Object.keys(c).length&&(this.overrides={...this.overrides,...c},this.els&&this.applyConfig())}registerActions(t){this.registry.register(t)}unregisterAction(t){return this.propActionNames.delete(t),this.registry.unregister(t)}get headers(){return this.hooks.headers}set headers(t){this.hooks.headers=t}get fetch(){return this.hooks.fetch}set fetch(t){this.hooks.fetch=t}get actionNames(){return this.registry.names()}setPropActions(t){let n=new Set(t.map(e=>e.name));for(let e of this.propActionNames)n.has(e)||this.registry.unregister(e);t.length&&this.registry.register(t),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(t){let n=t.trim();if(!n||this.running)return;this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),await this.activate(),this.els.input.value="",this.autosize();let e={message:n,hidden:!1};for(let r=0;e;r++){let o=await this.runTurn(e.message,e.hidden);if(e=null,o.status!=="done"||o.stopped||!this.registry.size)break;let{calls:a}=_(o.content);if(!a.length)break;o.actions=a.map(d=>({id:d.id,name:d.name,args:d.ok?d.args:void 0,status:"pending"}));let c=this.config.maxActionRounds??5;if(r>=c){for(let d of o.actions)Object.assign(d,{status:"error",error:"Automatic action limit reached"});this.updateMessage(o),this.showNotice(this.strings.actionLimit(c));break}this.updateMessage(o);let l=await this.runActions(o,a);l&&(e={message:st(l,this.server?.maxMessageLength??4e3),hidden:!0})}}async runTurn(t,n){this.pushMessage({role:"user",content:t,hidden:n});let e={role:"assistant",content:"",status:"streaming",startedAt:Date.now()};this.pushMessage(e),this.setRunning(new AbortController),this.emit("dewee:send",{message:t,agent:this.agentId,conversationId:this.conversationId,auto:n||void 0});try{await this.client().chat(this.chatBody(t),r=>this.onStreamEvent(e,r),this.running.signal),e.status==="streaming"&&(e.status="done")}catch(r){r.name==="AbortError"?(e.status="done",e.stopped=!0,e.content||(e.content=`_${this.strings.stopped}_`)):(e.status="error",this.showError(e,r))}finally{this.finishThinking(e),this.updateMessage(e),this.setRunning(null),e.status==="done"&&(e.actionsHash&&!e.stopped&&this.setAck(e.actionsHash),this.emit("dewee:reply",{content:e.content,agent:this.agentId,conversationId:this.conversationId}),this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.setAttribute("data-unread",""))}return e}chatBody(t){let n={message:t,agent:this.agentId,conversationId:this.conversationId};if(this.registry.size){n.actions=this.registry.manifest();let r=this.getAck();r&&(n.actionsHash=r)}let e=this.pageContext();return e!==void 0&&(n.pageContext=e),n}pageContext(){let t=this.hooks.getPageContext;if(t)try{let n=t();if(n==null)return;let e=new TextEncoder().encode(JSON.stringify(n)).length;return e<=C.maxPageContextBytes?n:(console.warn(`[dewee-webchat] getPageContext() returned ${e} bytes; the limit is ${C.maxPageContextBytes}. Context not sent.`),{truncated:!0})}catch(n){console.warn("[dewee-webchat] getPageContext() failed:",n);return}}ackKey(){return`dewee-webchat:actions:${this.config.endpoint}:${this.agentId}:${this.conversationId}`}getAck(){return this.acks.get(this.ackKey())??(this.config.persist!==!1?T.get(this.ackKey())??void 0:void 0)}setAck(t){this.acks.set(this.ackKey(),t),this.config.persist!==!1&&T.set(this.ackKey(),t)}async runActions(t,n){let e=new AbortController;this.setRunning(e);let r=[],o={agent:this.agentId,conversationId:this.conversationId};try{for(let[a,c]of n.entries()){let l=t.actions[a],d=c.ok?this.registry.get(c.name)?.sensitivity:void 0,g=c.ok?c.args:void 0;this.emit("dewee:action",{phase:"start",id:c.id,name:c.name,sensitivity:d,args:g,...o});let p=await ct(c,{registry:this.registry,confirm:(u,m)=>this.confirmAction(u,m,e.signal),signal:e.signal,timeoutMs:this.config.actionTimeoutMs,...o,onStatus:u=>{l.status=u,this.updateMessage(t)}});p.error&&(l.error=p.error),this.updateMessage(t),r.push(p),this.emit("dewee:action",{phase:"result",id:p.id,name:p.name,sensitivity:d,args:g,status:p.status,result:p.result,error:p.error,...o})}}finally{this.setRunning(null)}return e.signal.aborted?null:r}confirmAction(t,n,e){return this.hooks.confirm?this.hooks.confirm(t,n):(this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),dt(this.els.panel,this.strings,t,n,e))}showNotice(t){let n=document.createElement("div");n.className="notice",n.setAttribute("role","status"),n.textContent=t,this.els.log.appendChild(n),this.scrollToBottom(!0)}stop(){this.running?.abort()}newConversation(){this.stop(),this.conversationId=mt(),this.config.persist!==!1&&T.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.stop(),this.mql?.removeEventListener("change",this.onScheme)}attributeChangedCallback(){this.els&&this.applyConfig()}emit(t,n){this.dispatchEvent(new CustomEvent(t,{detail:n,bubbles:!0,composed:!0}))}client(){let t=this.config,n=[t.endpoint,t.gatewayUrl,t.gatewayToken].join("|");return(!this.api||n!==this.apiKey)&&(this.apiKey=n,this.api=new E({endpoint:t.endpoint,gatewayUrl:t.gatewayUrl,gatewayToken:t.gatewayToken,turnstile:e=>this.challenge(e),headers:()=>{let e=this.hooks.headers;return(typeof e=="function"?e():e)??{}},fetch:(e,r)=>(this.hooks.fetch??globalThis.fetch)(e,r)})),this.api}convKey(){return`dewee-webchat:conv:${this.config.endpoint}:${this.config.gatewayUrl||""}:${this.agentId}`}applyTheme(){let t=this.config.theme||"light",n=t==="dark"||t==="auto"&&!!this.mql?.matches;this.setAttribute("data-theme",n?"dark":"light")}applyConfig(){let t=this.config;this.strings=U(t.locale);let n=this.strings;this.setAttribute("data-position",t.position||"bottom-right"),this.setAttribute("data-mode",t.mode||"floating"),t.theme==="auto"&&!this.mql&&(this.mql=matchMedia("(prefers-color-scheme: dark)"),this.mql.addEventListener("change",this.onScheme)),this.applyTheme();let e=(o,a)=>a!==void 0&&a!==""?this.style.setProperty(o,String(a)):this.style.removeProperty(o);e("--dw-accent",t.accentColor),e("--dw-width",t.width),e("--dw-height",t.height),e("--dw-z",t.zIndex);let r=this.els;if(r.title.textContent=t.title||n.title,r.avatar.replaceChildren(),t.avatar){let o=document.createElement("img");o.src=t.avatar,o.alt="",r.avatar.appendChild(o)}else r.avatar.textContent=(t.title||n.title).trim().charAt(0).toUpperCase();if(r.launcher.innerHTML=t.avatar&&t.launcherAvatar?"":x.chat,t.avatar&&t.launcherAvatar){let o=document.createElement("img");o.src=t.avatar,o.alt="",r.launcher.appendChild(o)}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.input.placeholder=t.placeholder||n.placeholder,r.foot.hidden=!!t.hideBranding,r.foot.querySelector(".by").textContent=n.poweredBy+" ",this.renderSubtitle(),this.updateSendButton(),this.activated&&this.api&&this.apiKey!==[t.endpoint,t.gatewayUrl,t.gatewayToken].join("|")?(this.activated=!1,this.server=null,this.activate()):this.activated&&t.agent&&t.agent!==this.agentId&&this.server?this.switchAgent(t.agent):this.activated&&this.renderLog()}renderShell(){this.root.innerHTML=`
|
|
305
|
-
<style>${
|
|
308
|
+
`;var Ue=5e3,Se=["show-reasoning","show-tool-calls","allow-agent-switch","open","persist","hide-branding","launcher-avatar"],Ee=["endpoint","agent","title","subtitle","greeting","intro","placeholder","suggestions","avatar","position","mode","theme","accent-color","locale","gateway-url","gateway-token","width","height","z-index",...Se],Ae=i=>i.replace(/-([a-z])/g,(s,e)=>e.toUpperCase()),Ye=i=>i!==null&&!/^(false|0|off|no)$/i.test(i),Ce=()=>{let i=crypto.getRandomValues(new Uint8Array(9));return Array.from(i,s=>"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"[s&63]).join("")},Fe=i=>i.replace(/^mcp_[^_]+(?:_[^_]+)*?__/,"").replace(/_/g," "),R={get(i){try{return localStorage.getItem(i)}catch{return null}},set(i,s){try{localStorage.setItem(i,s)}catch{}}},We=null;function Ge(){return We??(We=new Promise((i,s)=>{if(window.turnstile)return i();let e=document.createElement("script");e.src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit",e.async=!0,e.onload=()=>i(),e.onerror=()=>s(new Error("Could not load Turnstile")),document.head.appendChild(e)}))}var Qe=typeof HTMLElement>"u"?class{}:HTMLElement,M=class extends Qe{constructor(){super();u(this,"root");u(this,"overrides",{});u(this,"api",null);u(this,"apiKey","");u(this,"server",null);u(this,"agentId","");u(this,"conversationId","");u(this,"messages",[]);u(this,"running",null);u(this,"jobAccessLaunch",null);u(this,"activated",!1);u(this,"strings",Z());u(this,"mql",null);u(this,"registry",new D);u(this,"propActionNames",new Set);u(this,"hooks",{});u(this,"acks",new Map);u(this,"cooldown",new H(e=>this.renderCooldown(e),()=>this.endCooldown()));u(this,"els");u(this,"onScheme",()=>this.applyTheme());u(this,"pendingFrame",0);u(this,"following",!0);this.root=this.attachShadow({mode:"open"})}static get observedAttributes(){return Ee}get config(){let e={endpoint:"/api/dewee"};for(let t of Ee){let n=this.getAttribute(t);n!==null&&(Se.includes(t)?e[Ae(t)]=Ye(n):t==="suggestions"?e.suggestions=n.trim().startsWith("[")?tt(n,[]):n.split("|").map(o=>o.trim()).filter(Boolean):t==="z-index"?e.zIndex=Number(n):e[Ae(t)]=n)}return{...e,...this.overrides,...this.hooks}}configure(e){let{actions:t,confirm:n,getPageContext:o,headers:r,fetch:a,...l}=e,c=d=>Object.prototype.hasOwnProperty.call(e,d);c("actions")&&this.setPropActions(t??[]),c("confirm")&&(this.hooks.confirm=n),c("getPageContext")&&(this.hooks.getPageContext=o),c("headers")&&(this.hooks.headers=r),c("fetch")&&(this.hooks.fetch=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.registry.names()}setPropActions(e){let t=new Set(e.map(n=>n.name));for(let n of this.propActionNames)t.has(n)||this.registry.unregister(n);e.length&&this.registry.register(e),this.propActionNames=t}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 t=e.trim();if(!t||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 n={message:t,hidden:!1};for(let o=0;n;o++){let r=await this.runTurn(n.message,n.hidden);if(n=null,r.status!=="done"||r.stopped||!this.registry.size)break;let{calls:a}=K(r.content);if(!a.length)break;r.actions=a.map(d=>({id:d.id,name:d.name,args:d.ok?d.args:void 0,status:"pending"}));let l=this.config.maxActionRounds??5;if(o>=l){for(let d of r.actions)Object.assign(d,{status:"error",error:"Automatic action limit reached"});this.updateMessage(r),this.showNotice(this.strings.actionLimit(l));break}this.updateMessage(r);let c=await this.runActions(r,a);c&&(n={message:he(c,this.server?.maxMessageLength??4e3),hidden:!0})}}async runTurn(e,t){this.pushMessage({role:"user",content:e,hidden:t});let n={role:"assistant",content:"",status:"streaming",startedAt:Date.now()};this.pushMessage(n),this.setRunning(new AbortController),this.emit("dewee:send",{message:e,agent:this.agentId,conversationId:this.conversationId,auto:t||void 0});try{await this.client().chat(this.chatBody(e),o=>this.onStreamEvent(n,o),this.running.signal),n.status==="streaming"&&(n.status="done")}catch(o){o.name==="AbortError"?(n.status="done",n.stopped=!0,n.content||(n.content=`_${this.strings.stopped}_`)):(n.status="error",this.showError(n,o))}finally{this.finishThinking(n),this.updateMessage(n),this.setRunning(null),n.status==="done"&&(n.actionsHash&&!n.stopped&&this.setAck(n.actionsHash),this.emit("dewee:reply",{content:n.content,agent:this.agentId,conversationId:this.conversationId}),this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.setAttribute("data-unread",""))}return n}chatBody(e){let t={message:e,agent:this.agentId,conversationId:this.conversationId};if(this.registry.size){t.actions=this.registry.manifest();let o=this.getAck();o&&(t.actionsHash=o)}let n=this.pageContext();return n!==void 0&&(t.pageContext=n),t}pageContext(){let e=this.hooks.getPageContext;if(e)try{let t=e();if(t==null)return;let n=new TextEncoder().encode(JSON.stringify(t)).length;return n<=S.maxPageContextBytes?t:(console.warn(`[dewee-webchat] getPageContext() returned ${n} bytes; the limit is ${S.maxPageContextBytes}. Context not sent.`),{truncated:!0})}catch(t){console.warn("[dewee-webchat] getPageContext() failed:",t);return}}ackKey(){return`dewee-webchat:actions:${this.config.endpoint}:${this.agentId}:${this.conversationId}`}getAck(){return this.acks.get(this.ackKey())??(this.config.persist!==!1?R.get(this.ackKey())??void 0:void 0)}setAck(e){this.acks.set(this.ackKey(),e),this.config.persist!==!1&&R.set(this.ackKey(),e)}async runActions(e,t){let n=new AbortController;this.setRunning(n);let o=[],r={agent:this.agentId,conversationId:this.conversationId};try{for(let[a,l]of t.entries()){let c=e.actions[a],d=l.ok?this.registry.get(l.name)?.sensitivity:void 0,h=l.ok?l.args:void 0;this.emit("dewee:action",{phase:"start",id:l.id,name:l.name,sensitivity:d,args:h,...r});let p=await me(l,{registry:this.registry,confirm:(g,f)=>this.confirmAction(g,f,n.signal),signal:n.signal,timeoutMs:this.config.actionTimeoutMs,...r,onStatus:g=>{c.status=g,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:d,args:h,status:p.status,result:p.result,error:p.error,...r})}}finally{this.setRunning(null)}return n.signal.aborted?null:o}confirmAction(e,t,n){return this.hooks.confirm?this.hooks.confirm(e,t):(this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),ye(this.els.panel,this.strings,e,t,n))}showNotice(e){let t=document.createElement("div");t.className="notice",t.setAttribute("role","status"),t.textContent=e,this.els.log.appendChild(t),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 we(t=>this.client().jobAccess(t),e.signal),this.showNotice(this.strings.jobAccessOpened)}catch(t){if(e.signal.aborted)return;t instanceof E?this.showNotice(t.code==="popup_blocked"?this.strings.jobAccessPopupBlocked:t.code==="popup_closed"?this.strings.jobAccessPopupClosed:this.strings.jobAccessUnavailable):t instanceof x&&j(t.code)?this.showError(null,t):this.showNotice(this.strings.jobAccessUnavailable)}finally{this.jobAccessLaunch=null,this.els.jobAccess.disabled=!1}}renderLink(e){let t=this.strings,n=document.createElement("div");n.className="msg assistant link";let o=document.createElement("div");o.className="bubble";let r=document.createElement("div");r.className="md";let a=d=>{let h=document.createElement("p");return h.textContent=d,h},l=document.createElement("code");l.textContent=e.proofCode;let c=document.createElement("p");if(c.appendChild(l),r.append(a(t.linkIntro),c),e.deepLinks.length){let d=document.createElement("ul");for(let h of e.deepLinks){let p=document.createElement("li"),g=h.displayName||h.name;p.textContent=t.linkContinueOn(et(h.channelType))+(g?` \xB7 ${g}`:""),d.appendChild(p)}r.appendChild(d)}else r.appendChild(a(t.linkNoTargets));r.appendChild(a(t.linkExpires(Math.max(1,Math.round((e.expiresAt-Date.now())/6e4))))),o.appendChild(r),n.appendChild(o),this.messages.length||this.els.log.replaceChildren(),this.els.log.appendChild(n),this.scrollToBottom(!0)}newConversation(){this.stop(),this.conversationId=Ce(),this.config.persist!==!1&&R.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,t){this.dispatchEvent(new CustomEvent(e,{detail:t,bubbles:!0,composed:!0}))}client(){let e=this.config,t=[e.endpoint,e.gatewayUrl,e.gatewayToken].join("|");return(!this.api||t!==this.apiKey)&&(this.apiKey=t,this.api=new I({endpoint:e.endpoint,gatewayUrl:e.gatewayUrl,gatewayToken:e.gatewayToken,turnstile:n=>this.challenge(n),headers:()=>{let n=this.hooks.headers;return(typeof n=="function"?n():n)??{}},fetch:(n,o)=>(this.hooks.fetch??globalThis.fetch)(n,o)})),this.api}convKey(){return`dewee-webchat:conv:${this.config.endpoint}:${this.config.gatewayUrl||""}:${this.agentId}`}applyTheme(){let e=this.config.theme||"light",t=e==="dark"||e==="auto"&&!!this.mql?.matches;this.setAttribute("data-theme",t?"dark":"light")}applyConfig(){let e=this.config;this.strings=Z(e.locale);let t=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 n=(r,a)=>a!==void 0&&a!==""?this.style.setProperty(r,String(a)):this.style.removeProperty(r);n("--dw-accent",e.accentColor),n("--dw-width",e.width),n("--dw-height",e.height),n("--dw-z",e.zIndex);let o=this.els;if(o.title.textContent=e.title||t.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||t.title).trim().charAt(0).toUpperCase();if(o.launcher.innerHTML=e.avatar&&e.launcherAvatar?"":A.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",t.open),o.close.setAttribute("aria-label",t.close),o.close.title=t.close,o.newChat.setAttribute("aria-label",t.newChat),o.newChat.title=t.newChat,o.jobAccess.setAttribute("aria-label",t.jobAccess),o.jobAccess.title=t.jobAccess,o.input.placeholder=e.placeholder||t.placeholder,o.foot.hidden=!!e.hideBranding,o.foot.querySelector(".by").textContent=t.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>${ke}</style>
|
|
306
310
|
<button class="launcher" part="launcher" aria-expanded="false" aria-haspopup="dialog"></button>
|
|
307
311
|
<section class="panel" part="panel" role="dialog" aria-label="Chat">
|
|
308
312
|
<header class="head" part="header">
|
|
@@ -311,19 +315,22 @@ textarea::placeholder { color: var(--dw-muted); }
|
|
|
311
315
|
<div class="title"></div>
|
|
312
316
|
<div class="subtitle"><span class="dot"></span><span class="status"></span><select class="agent-select" hidden></select></div>
|
|
313
317
|
</div>
|
|
314
|
-
<button class="icon-btn new">${
|
|
315
|
-
<button class="icon-btn
|
|
318
|
+
<button class="icon-btn new">${A.newChat}</button>
|
|
319
|
+
<button class="icon-btn job-access" hidden>${A.jobAccess}</button>
|
|
320
|
+
<button class="icon-btn close">${A.close}</button>
|
|
316
321
|
</header>
|
|
317
322
|
<div class="log" part="log" role="log" aria-live="polite"></div>
|
|
318
323
|
<div class="challenge"><slot name="challenge"></slot></div>
|
|
319
324
|
<form class="composer" part="composer">
|
|
325
|
+
<div class="cooldown" part="cooldown" aria-hidden="true" hidden></div>
|
|
326
|
+
<div class="sr-only announcer" role="status" aria-live="polite"></div>
|
|
320
327
|
<div class="box">
|
|
321
328
|
<textarea rows="1" maxlength="4000"></textarea>
|
|
322
329
|
<button class="send" type="submit"></button>
|
|
323
330
|
</div>
|
|
324
331
|
<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>
|
|
325
332
|
</form>
|
|
326
|
-
</section>`;let
|
|
327
|
-
`);return a&&(
|
|
333
|
+
</section>`;let e=n=>this.root.querySelector(n);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 t=this.els;t.launcher.addEventListener("click",()=>this.toggle()),t.close.addEventListener("click",()=>this.close()),t.log.addEventListener("scroll",()=>{this.following=this.nearBottom()},{passive:!0}),t.newChat.addEventListener("click",()=>this.newConversation()),t.jobAccess.addEventListener("click",()=>{this.openJobAccess()}),t.select.addEventListener("change",()=>this.switchAgent(t.select.value)),e("form").addEventListener("submit",n=>{n.preventDefault(),this.running?this.stop():this.send(t.input.value)}),t.input.addEventListener("keydown",n=>{n.key==="Enter"&&!n.shiftKey&&!n.isComposing&&n.keyCode!==229&&(n.preventDefault(),this.running||this.send(t.input.value))}),t.input.addEventListener("input",()=>{this.autosize(),this.updateSendButton()}),t.panel.addEventListener("keydown",n=>{n.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?A.stop:A.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:Ue),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,t=this.config,n=this.server?.agents??[],o=t.allowAgentSwitch!==!1&&!!this.server?.allowAgentSwitch&&n.length>1;e.select.hidden=!o,e.status.hidden=o,o&&(e.select.replaceChildren(...n.map(a=>new Option(a.name||a.id,a.id,!1,a.id===this.agentId))),e.select.setAttribute("aria-label","Agent"));let r=n.find(a=>a.id===this.agentId);e.status.textContent=t.subtitle||(r?.name&&r.name!==t.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,t=n=>!!n&&(this.server.agents.length===0||this.server.agents.some(o=>o.id===n));this.agentId=t(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,t=e?R.get(this.convKey()):null;if(this.conversationId=t||Ce(),e&&!t&&R.set(this.convKey(),this.conversationId),this.messages=[],this.renderLog(),!!t)try{let n=await this.client().history(this.agentId,this.conversationId);this.messages=Ze(n.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 t of this.messages)e.appendChild(this.renderMessage(t));e.scrollTop=e.scrollHeight}renderWelcome(){let e=this.config,t=this.strings,n=document.createElement("div");n.className="welcome";let o=document.createElement("h2");o.textContent=e.greeting||t.greeting;let r=document.createElement("p");if(r.textContent=e.intro||t.greetingBody,n.append(o,r),e.suggestions?.length){let a=document.createElement("div");a.className="suggestions";for(let l of e.suggestions){let c=document.createElement("button");c.className="chip",c.type="button",c.textContent=l,c.addEventListener("click",()=>this.send(l)),a.appendChild(c)}n.appendChild(a)}return n}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 t=document.createElement("div");t.className=`msg ${e.role}${e.status==="error"?" error":""}`,t.hidden=!!e.hidden;let n=document.createElement("div");n.className="bubble",t.appendChild(n);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"&&n.appendChild(o),n.appendChild(r),e.role==="assistant"&&n.appendChild(a),e.view={root:t,trace:o,md:r,tools:new Map,actions:a},this.updateMessage(e),t}updateMessage(e){let t=e.view;if(!t)return;let n=this.config;if(e.role==="user"){t.md.textContent=e.content,t.root.classList.toggle("refused",!!e.refusal);let a=t.root.querySelector(".refusal");e.refusal&&!a&&(a=document.createElement("div"),a.className="refusal",t.root.appendChild(a)),a&&e.refusal?a.textContent=`\u26A0\uFE0F ${e.refusal}`:a?.remove();return}if(t.root.classList.toggle("error",e.status==="error"),n.showReasoning!==!1&&e.thinking){t.thinking||(t.thinking=document.createElement("details"),t.thinking.className="thinking",t.thinking.innerHTML='<summary></summary><div class="thinking-body"></div>',t.trace.prepend(t.thinking));let a=e.status==="streaming"&&!e.thinkingMs,l=a?this.strings.thinking:e.thinkingMs?this.strings.thoughtFor(Math.max(1,Math.round(e.thinkingMs/1e3))):this.strings.reasoning,c=t.thinking.querySelector("summary");c.innerHTML=`${a?'<span class="spin"></span>':A.brain}<span></span>${A.down.replace("<svg",'<svg class="chev"')}`,c.querySelector("span:not(.spin)").textContent=l,t.thinking.querySelector(".thinking-body").textContent=e.thinking}else t.thinking&&(t.thinking.remove(),t.thinking=void 0);if(n.showToolCalls!==!1)for(let a of e.toolCalls??[])this.renderTool(t,a);else t.tools.forEach(a=>a.remove()),t.tools.clear();t.trace.hidden=!t.trace.childElementCount;let o=this.registry.size||e.actions?le(e.content):e.content,r=e.status==="streaming"&&!o;t.md.hidden=!r&&!o&&!!e.actions?.length,r?t.md.innerHTML=`<span class="typing" aria-label="${this.strings.thinking}"><i></i><i></i><i></i></span>`:(t.md.replaceChildren(L(document,o)),t.md.classList.toggle("cursor",e.status==="streaming")),this.renderActions(t,e.actions??[])}renderActions(e,t){e.actions.hidden=!t.length,e.actions.replaceChildren(...t.map(n=>{let o=document.createElement("div");o.className="action",o.dataset.status=n.status;let r=n.status==="running"||n.status==="awaiting-confirmation";o.innerHTML=`${r?'<span class="spin"></span>':A.action}<span class="action-name"></span><span class="action-state"></span>`,o.querySelector(".action-name").textContent=n.name||"?",o.querySelector(".action-state").textContent=this.strings.actionStatus[n.status];let a=[n.args&&Object.keys(n.args).length?JSON.stringify(n.args):"",n.error??""].filter(Boolean).join(`
|
|
334
|
+
`);return a&&(o.title=a),o}))}renderTool(e,t){let n=e.tools.get(t.id);n||(n=document.createElement("details"),n.className="tool",n.innerHTML=`<summary><span class="lead"></span><span class="tool-name"></span><span class="tool-state"></span>${A.down.replace("<svg",'<svg class="chev"')}</summary><div class="tool-body"></div>`,e.tools.set(t.id,n),e.trace.appendChild(n)),n.dataset.status=t.status,n.querySelector(".lead").innerHTML=t.status==="running"?'<span class="spin"></span>':A.tool;let o=n.querySelector(".tool-name");o.textContent=Fe(t.name),o.setAttribute("title",t.name),n.querySelector(".tool-state").textContent=t.status==="running"?this.strings.toolRunning:t.status==="error"?this.strings.toolError:this.strings.toolDone;let r=n.querySelector(".tool-body");r.replaceChildren();let a=(l,c)=>{if(c==null||c==="")return;let d=document.createElement("div");d.className="label",d.textContent=l;let h=document.createElement("pre");h.textContent=typeof c=="string"?nt(c):JSON.stringify(c,null,2),r.append(d,h)};a(this.strings.args,t.arguments),a(this.strings.result,t.result)}onStreamEvent(e,t){switch(t.type){case"start":t.actionsHash&&(e.actionsHash=t.actionsHash),t.conversationId&&t.conversationId!==this.conversationId&&(this.conversationId=t.conversationId,this.config.persist!==!1&&R.set(this.convKey(),t.conversationId));break;case"thinking":e.thinking=(e.thinking||"")+t.text;break;case"delta":this.finishThinking(e),e.content+=t.text;break;case"tool_call":this.finishThinking(e),(e.toolCalls??(e.toolCalls=[])).push({id:t.id,name:t.name,arguments:t.arguments,status:"running"});break;case"tool_result":{let n=e.toolCalls?.find(o=>o.id===t.id)??(e.toolCalls??(e.toolCalls=[]))[e.toolCalls.push({id:t.id,name:t.name,status:"running"})-1];n.status=t.isError?"error":"done",n.result=t.result,n.isError=t.isError;break}case"done":this.finishThinking(e),t.content&&t.content.length>=e.content.length&&(e.content=t.content),e.status="done";break;case"error":e.status="error",this.showError(e,new x(t.message,500,t.code,t.remediation,t.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 t=this.els.log;(e||this.nearBottom())&&(t.scrollTop=t.scrollHeight,this.following=!0)}showError(e,t){let{code:n,remediation:o,retryAfterMs:r}=t,l=(j(n)?this.strings.identityErrors[n]:B(n)?this.strings.admissionErrors[n]:ne(n)?this.strings.linkErrors[n]:"")||t.message||this.strings.errorGeneric;if(this.emit("dewee:error",{message:l,code:n,...o&&{remediation:o},...r&&{retryAfterMs:r}}),n==="RATE_LIMITED"&&this.startCooldown(r),e&&B(n)&&this.refuseInline(e,n,l))return;if(e){e.content=e.content?`${e.content}
|
|
328
335
|
|
|
329
|
-
> \u26A0\uFE0F ${
|
|
336
|
+
> \u26A0\uFE0F ${l}`:`\u26A0\uFE0F ${l}`,e.status="error",this.updateMessage(e);return}let c=document.createElement("div");c.className="msg error",c.innerHTML='<div class="bubble"></div>',c.firstElementChild.textContent=`\u26A0\uFE0F ${l}`,this.els.log.appendChild(c)}refuseInline(e,t,n){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()),t!=="POLICY_DENIED"||e.content)?!1:(e.status="error",e.hidden=!0,e.view&&(e.view.root.hidden=!0),r.refusal=n,this.updateMessage(r),!0)}async challenge(e){await Ge();let t=document.createElement("div");t.slot="challenge",this.appendChild(t);try{return await new Promise((n,o)=>{window.turnstile.render(t,{sitekey:e,appearance:"interaction-only",theme:this.getAttribute("data-theme")==="dark"?"dark":"light",callback:n,"error-callback":()=>o(new x("Verification failed",403,"turnstile_failed"))})})}finally{t.remove()}}};function Ze(i){return i.forEach((s,e)=>{if(s.role==="user"){s.content=W(s.content),V(s.content)&&(s.hidden=!0);return}if(!s.content.includes("```dewee-action"))return;let{calls:t}=K(s.content);if(!t.length)return;let n=i[e+1],o=n?.role==="user"?W(n.content):"",r=V(o)?de(o):[];s.actions=t.map(a=>{let l=r.find(d=>d.id===a.id),c=l?l.status==="ok"?"done":l.status:"error";return{id:a.id,name:a.name,args:a.ok?a.args:void 0,status:c,error:l?l.error:"Not run"}})}),i}var Xe={telegram:"Telegram",discord:"Discord",zalo:"Zalo",slack:"Slack",whatsapp:"WhatsApp",messenger:"Messenger",feishu:"Feishu",line:"LINE"};function et(i){let s=i.toLowerCase().split(/[_-]/)[0];return Xe[s]??(i?i.charAt(0).toUpperCase()+i.slice(1):"chat")}function tt(i,s){try{return JSON.parse(i)}catch{return s}}function nt(i){let s=i.trim();if(!/^[[{]/.test(s))return i;try{return JSON.stringify(JSON.parse(s),null,2)}catch{return i}}function X(i="dewee-chat"){typeof window>"u"||!window.customElements||customElements.get(i)||customElements.define(i,class extends M{})}function it(i={},s){X();let e=document.createElement("dewee-chat");return e.configure(i),((typeof s=="string"?document.querySelector(s):s)??document.body).appendChild(e),e}X();var st=document.currentScript,$=st?.dataset;if($&&$.endpoint&&$.autoMount!=="false"){let i=()=>{let s=document.createElement("dewee-chat");for(let[e,t]of Object.entries($))e==="autoMount"||t===void 0||s.setAttribute(e.replace(/[A-Z]/g,n=>"-"+n.toLowerCase()),t);document.body.appendChild(s)};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",i):i()}window.DeweeWebchat=ee;})();
|