dewee-webchat 0.1.0 → 0.2.0
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 +69 -3
- package/astro/DeweeChat.astro +21 -21
- package/dist/chunk-JX6AH37X.js +111 -0
- package/dist/{chunk-RGAYYTL7.js → chunk-YV6PXYJZ.js} +607 -22
- package/dist/dewee-webchat.js +92 -15
- package/dist/index.d.ts +97 -5
- package/dist/index.js +2 -2
- package/dist/{protocol-CS8_4zC0.d.ts → protocol-B72Ry-fY.d.ts} +22 -1
- package/dist/react.d.ts +6 -3
- package/dist/react.js +10 -5
- package/dist/server.d.ts +27 -3
- package/dist/server.js +28 -5
- package/dist/vue.d.ts +50 -4
- package/dist/vue.js +12 -5
- package/package.json +99 -99
- package/dist/chunk-MKTHKYLY.js +0 -10
package/dist/dewee-webchat.js
CHANGED
|
@@ -1,13 +1,42 @@
|
|
|
1
|
-
"use strict";(()=>{var
|
|
1
|
+
"use strict";(()=>{var U=Object.defineProperty;var wt=(i,s,t)=>s in i?U(i,s,{enumerable:!0,configurable:!0,writable:!0,value:t}):i[s]=t;var xt=(i,s)=>{for(var t in s)U(i,t,{get:s[t],enumerable:!0})};var h=(i,s,t)=>wt(i,typeof s!="symbol"?s+"":s,t);var K={};xt(K,{ApiClient:()=>S,ApiError:()=>v,DeweeChatElement:()=>L,defineDeweeChat:()=>V,mount:()=>Ot,renderMarkdown:()=>E});var F="dewee-action",G="dewee-action-result",I={maxCalls:8,maxBlockBytes:8192},bt=/^[A-Za-z0-9_.:-]{1,64}$/,yt=/^\s{0,3}```\s*$/,W=i=>new RegExp("^\\s{0,3}```"+i.replace(/[.-]/g,"\\$&")+"\\s*$"),Y=W(F),Z=W(G);function _(i,s){let t=[];for(let e=0;e<i.length;e++){if(!s.test(i[e]))continue;let n=e,r=[],o=!1;for(e++;e<i.length;e++){if(yt.test(i[e])){o=!0;break}r.push(i[e])}t.push({start:n,end:Math.min(e,i.length-1),body:r,closed:o})}return t}var Q=(i,s)=>{let t=new Set;for(let e of s)for(let n=e.start;n<=e.end;n++)t.add(n);return i.filter((e,n)=>!t.has(n)).join(`
|
|
2
|
+
`).replace(/\n{3,}/g,`
|
|
2
3
|
|
|
3
|
-
`)
|
|
4
|
+
`).trim()};function H(i){let s=i.replace(/\r\n?/g,`
|
|
5
|
+
`).split(`
|
|
6
|
+
`),t=_(s,Y),e=[],n=new Set;return t.forEach((r,o)=>{let a=`call-${o+1}`,l=r.body.join(`
|
|
7
|
+
`),c=(m,w=a,x="")=>e.push({ok:!1,id:w,name:x,error:m});if(o>=I.maxCalls)return c(`Too many action calls in one reply (max ${I.maxCalls})`);if(!r.closed)return c("Unclosed dewee-action block");if(new TextEncoder().encode(l).length>I.maxBlockBytes)return c(`Action block exceeds ${I.maxBlockBytes} bytes`);let g;try{g=JSON.parse(l)}catch{return c("Action block is not valid JSON")}if(typeof g!="object"||g===null||Array.isArray(g))return c("Action block must be a JSON object");let p=typeof g.id=="string"&&bt.test(g.id)?g.id:a,d=typeof g.name=="string"?g.name.slice(0,64):"";if(n.has(p))return c(`Duplicate action call id "${p}"`,`${p}-${o+1}`,d);if(n.add(p),!d)return c("Action name is required",p);let u=g.args??{};if(typeof u!="object"||u===null||Array.isArray(u))return c("args must be a JSON object",p,d);e.push({ok:!0,id:p,name:d,args:u})}),{text:t.length?Q(s,t):i,calls:e}}function X(i){if(!i.includes("```"+F))return i;let s=i.replace(/\r\n?/g,`
|
|
8
|
+
`).split(`
|
|
9
|
+
`);return Q(s,_(s,Y))}function B(i){return Z.test(i.trimStart().split(`
|
|
10
|
+
`,1)[0]??"")}function tt(i){let s=i.replace(/\r\n?/g,`
|
|
11
|
+
`).split(`
|
|
12
|
+
`),t=[];for(let e of _(s,Z))try{let n=JSON.parse(e.body.join(`
|
|
13
|
+
`));n&&typeof n.id=="string"&&["ok","denied","error"].includes(n.status)&&t.push(n)}catch{}return t}var P=i=>"```"+G+`
|
|
14
|
+
`+JSON.stringify(i)+"\n```";function et(i,s=4e3){let t=Math.max(64,Math.floor((s-16)/Math.max(1,i.length)));return i.map(n=>{let r={...n,result:O(n.result)};if(r.result===void 0&&delete r.result,P(r).length<=t)return P(r);let o=JSON.stringify(r.result??null),a=t-P({...r,result:{truncated:!0,preview:""}}).length-8,l=P({...r,result:{truncated:!0,preview:o.slice(0,Math.max(0,a))}});return l.length<=t?l:P({id:n.id,name:n.name.slice(0,64),status:n.status,result:{truncated:!0}})}).join(`
|
|
15
|
+
|
|
16
|
+
`).slice(0,s)}function O(i){if(i!==void 0)try{let s=JSON.stringify(i);return s===void 0?null:JSON.parse(s)}catch{return"[unserializable result]"}}var z=i=>i===null?"null":Array.isArray(i)?"array":typeof i=="number"?Number.isInteger(i)?"integer":"number":typeof i,vt=(i,s)=>{let t=z(i);return t===s||s==="number"&&t==="integer"};function R(i,s,t="args",e=0){if(!s||typeof s!="object")return null;if(e>32)return`${t}: schema is nested too deeply`;let n=s;if(n.type!==void 0){let r=Array.isArray(n.type)?n.type:[n.type];if(!r.some(o=>vt(i,o)))return`${t}: expected ${r.join(" or ")}, got ${z(i)}`}if(Array.isArray(n.enum)&&!n.enum.some(r=>nt(r,i)))return`${t}: must be one of ${n.enum.map(r=>JSON.stringify(r)).join(", ")}`;if("const"in n&&!nt(n.const,i))return`${t}: must equal ${JSON.stringify(n.const)}`;if(typeof i=="string"){if(typeof n.minLength=="number"&&i.length<n.minLength)return`${t}: shorter than ${n.minLength} characters`;if(typeof n.maxLength=="number"&&i.length>n.maxLength)return`${t}: longer than ${n.maxLength} characters`;if(typeof n.pattern=="string"){let r=null;try{r=new RegExp(n.pattern,"u")}catch{return`${t}: schema pattern is invalid`}if(!r.test(i))return`${t}: does not match ${n.pattern}`}}if(typeof i=="number"){if(typeof n.minimum=="number"&&i<n.minimum)return`${t}: must be >= ${n.minimum}`;if(typeof n.maximum=="number"&&i>n.maximum)return`${t}: must be <= ${n.maximum}`}if(Array.isArray(i)){if(typeof n.minItems=="number"&&i.length<n.minItems)return`${t}: needs at least ${n.minItems} items`;if(typeof n.maxItems=="number"&&i.length>n.maxItems)return`${t}: allows at most ${n.maxItems} items`;if(n.items&&typeof n.items=="object")for(let r=0;r<i.length;r++){let o=R(i[r],n.items,`${t}[${r}]`,e+1);if(o)return o}}if(z(i)==="object"){let r=i,o=n.properties&&typeof n.properties=="object"?n.properties:{};for(let a of Array.isArray(n.required)?n.required:[])if(!(a in r))return`${t}.${a}: is required`;for(let[a,l]of Object.entries(r))if(Object.prototype.hasOwnProperty.call(o,a)){let c=R(l,o[a],`${t}.${a}`,e+1);if(c)return c}else if(n.additionalProperties===!1)return`${t}.${a}: is not allowed`}return null}function nt(i,s){return JSON.stringify(i)===JSON.stringify(s)}var st=/^[a-z][a-z0-9_.-]{0,63}$/,D=["read","navigate","mutate","destructive"],C={maxActions:32,maxDescription:1e3,maxParametersBytes:4096,maxManifestBytes:16384,maxPageContextBytes:4096},kt="[[dewee-page v1]]",it="[[/dewee-page]]";function j(i){if(!i.startsWith(kt))return i;let s=i.indexOf(`
|
|
17
|
+
`+it);return s<0?i:i.slice(s+it.length+1).replace(/^\n+/,"")}var Ct=i=>i==="mutate"||i==="destructive",$=class{constructor(){h(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 t=Array.isArray(s)?s:[s];for(let e of t)At(e);if(new Set([...this.map.keys(),...t.map(e=>e.name)]).size>C.maxActions)throw new TypeError(`dewee-webchat: at most ${C.maxActions} page actions`);for(let e of t)this.map.set(e.name,e)}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 At(i){let s=t=>{throw new TypeError(`dewee-webchat: invalid page action ${JSON.stringify(i?.name)}: ${t}`)};(!i||typeof i!="object")&&s("not an object"),(typeof i.name!="string"||!st.test(i.name))&&s("name must match ^[a-z][a-z0-9_.-]{0,63}$"),(typeof i.description!="string"||i.description.length>C.maxDescription)&&s(`description must be a string up to ${C.maxDescription} chars`),D.includes(i.sensitivity)||s(`sensitivity must be one of ${D.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 ot(i,s){let t=l=>(s.onStatus?.("error"),{id:i.id,name:i.name,status:"error",error:l});if(!i.ok)return t(i.error);if(s.signal.aborted)return t("Cancelled");let e=s.registry.get(i.name);if(!e)return t(`Unknown action "${i.name}". Available: ${s.registry.names().join(", ")||"none"}`);let n=R(i.args,e.parameters??{type:"object"});if(n)return t(`Invalid arguments: ${n}`);if(Ct(e.sensitivity)){s.onStatus?.("awaiting-confirmation");let{handler:l,...c}=e,g=!1;try{g=await rt(Promise.resolve(s.confirm({...c,callId:i.id},i.args)),s.signal)===!0}catch{g=!1}if(!g||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 r=new AbortController,o=()=>r.abort();s.signal.addEventListener("abort",o,{once:!0});let a=setTimeout(o,s.timeoutMs??3e4);try{let l=await rt(Promise.resolve().then(()=>e.handler(i.args,{callId:i.id,conversationId:s.conversationId,agent:s.agent,signal:r.signal})),r.signal);return s.onStatus?.("done"),{id:i.id,name:i.name,status:"ok",result:O(l)??null}}catch(l){return t(r.signal.aborted?s.signal.aborted?"Cancelled":"Timed out":String(l?.message??l).slice(0,500)||"Action failed")}finally{clearTimeout(a),s.signal.removeEventListener("abort",o)}}function rt(i,s){return s.aborted?Promise.reject(new Error("aborted")):new Promise((t,e)=>{let n=()=>e(new Error("aborted"));s.addEventListener("abort",n,{once:!0}),i.then(t,e).finally(()=>s.removeEventListener("abort",n))})}var at="x-dewee-gateway-url",lt="x-dewee-gateway-token";var v=class extends Error{constructor(t,e,n){super(t);h(this,"status",e);h(this,"code",n)}},J={get(i){try{return localStorage.getItem(i)}catch{return null}},set(i,s){try{localStorage.setItem(i,s)}catch{}},del(i){try{localStorage.removeItem(i)}catch{}}},S=class{constructor(s){h(this,"o",s);h(this,"session",null);h(this,"config",null);h(this,"sessionPromise",null)}url(s,t){let e=this.o.endpoint.replace(/\/+$/,""),n=t?"?"+new URLSearchParams(t).toString():"";return`${e}/${s}${n}`}get storageKey(){return`dewee-webchat:session:${this.o.endpoint}`}headers(s=!1){let t={"content-type":"application/json"};return this.o.gatewayUrl&&this.o.gatewayToken&&(t[at]=this.o.gatewayUrl,t[lt]=this.o.gatewayToken),s&&this.session&&(t.authorization=`Bearer ${this.session.token}`),t}async parse(s){let t=await s.json().catch(()=>({}));if(!s.ok)throw new v(t?.error?.message||`HTTP ${s.status}`,s.status,t?.error?.code);return t}async getConfig(s=!1){return this.config&&!s?this.config:(this.config=await this.parse(await fetch(this.url("config"),{headers:this.headers()})),this.config)}ensureSession(){if(this.session&&this.session.expiresAt-Date.now()>864e5)return Promise.resolve(this.session);if(!this.session){let s=J.get(this.storageKey);if(s)try{let t=JSON.parse(s);if(t.expiresAt-Date.now()>864e5)return Promise.resolve(this.session=t);this.session=t}catch{}}return this.sessionPromise??(this.sessionPromise=this.createSession().finally(()=>this.sessionPromise=null))}async createSession(){let s=await this.getConfig(),t={};if(this.session?.token&&(t.token=this.session.token),s.turnstileSiteKey){if(!this.o.turnstile)throw new v("Verification is required but no Turnstile handler is set",403,"turnstile_required");t.turnstileToken=await this.o.turnstile(s.turnstileSiteKey)}let e=await this.parse(await fetch(this.url("session"),{method:"POST",headers:this.headers(),body:JSON.stringify(t)}));return this.session=e,J.set(this.storageKey,JSON.stringify(e)),e}forgetSession(){this.session=null,J.del(this.storageKey)}async history(s,t){await this.ensureSession();let e=await fetch(this.url("history",{agent:s,conversationId:t}),{headers:this.headers(!0)});return(await this.parse(e)).messages}async chat(s,t,e){await this.ensureSession();let n=await fetch(this.url("chat"),{method:"POST",headers:this.headers(!0),body:JSON.stringify(s),signal:e});n.status===401&&(this.forgetSession(),await this.ensureSession(),n=await fetch(this.url("chat"),{method:"POST",headers:this.headers(!0),body:JSON.stringify(s),signal:e})),(!n.ok||!n.body)&&await this.parse(n);let r=n.body.pipeThrough(new TextDecoderStream).getReader(),o="";for(;;){let{done:a,value:l}=await r.read();if(a)break;o+=l;let c;for(;(c=o.indexOf(`
|
|
18
|
+
|
|
19
|
+
`))>=0;){let g=o.slice(0,c);o=o.slice(c+2);let p=g.split(`
|
|
4
20
|
`).filter(d=>d.startsWith("data:")).map(d=>d.slice(5).trimStart()).join(`
|
|
5
|
-
`);if(
|
|
21
|
+
`);if(p)try{t(JSON.parse(p))}catch{}}}}};var St=0;function ct(i,s,t,e,n){let r=`dw-confirm-${++St}`,o=i.getRootNode(),a=o.activeElement,l=document.createElement("div");l.className="confirm-backdrop",l.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
|
+
<div class="confirm-action"><code></code><span class="sens"></span></div>
|
|
26
|
+
<p class="confirm-text"></p>
|
|
27
|
+
<p class="confirm-warn" hidden></p>
|
|
28
|
+
</div>
|
|
29
|
+
<pre class="confirm-args"></pre>
|
|
30
|
+
<div class="confirm-buttons">
|
|
31
|
+
<button type="button" class="btn deny"></button>
|
|
32
|
+
<button type="button" class="btn allow"></button>
|
|
33
|
+
</div>
|
|
34
|
+
</div>`;let c=w=>l.querySelector(w);c("h3").textContent=s.confirmTitle,c("code").textContent=t.name;let g=c(".sens");if(g.textContent=t.sensitivity,g.dataset.level=t.sensitivity,c(".confirm-text").textContent=t.description,t.sensitivity==="destructive"){let w=c(".confirm-warn");w.hidden=!1,w.textContent=s.confirmDestructive}let p=JSON.stringify(e,null,2),d=c(".confirm-args");p&&p!=="{}"?d.textContent=p:d.remove();let u=c(".deny"),m=c(".allow");return u.textContent=s.deny,m.textContent=s.allow,t.sensitivity==="destructive"&&m.classList.add("danger"),new Promise(w=>{let x=!1,y=A=>{x||(x=!0,n?.removeEventListener("abort",M),l.remove(),a?.focus?.(),w(A))},M=()=>y(!1);if(n?.aborted)return y(!1);n?.addEventListener("abort",M,{once:!0}),u.addEventListener("click",()=>y(!1)),m.addEventListener("click",()=>y(!0)),l.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(l),u.focus()})}var Et={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.`},Tt={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 q(i){return(i||(typeof document<"u"?document.documentElement.lang:"")||(typeof navigator<"u"?navigator.language:"")||"en").toLowerCase().startsWith("vi")?Tt:Et}var b={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 e=i.createElement(s);return t&&(e.className=t),e}function Mt(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 e=new RegExp(Pt.source,"g"),n=0;for(let r;r=e.exec(s);)if(r.index>n&&t.appendChild(i.createTextNode(s.slice(n,r.index))),n=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=Mt(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)}n<s.length&&t.appendChild(i.createTextNode(s.slice(n)))}var dt=i=>/^\s*\|?\s*:?-{2,}:?\s*(\|\s*:?-{2,}:?\s*)*\|?\s*$/.test(i),gt=i=>i.trim().replace(/^\||\|$/g,"").split("|").map(s=>s.trim());function E(i,s){let t=i.createDocumentFragment(),e=s.replace(/\r\n?/g,`
|
|
6
35
|
`).split(`
|
|
7
|
-
`),n=0;for(;n<
|
|
8
|
-
`),d.appendChild(u),
|
|
9
|
-
`))),
|
|
10
|
-
`)));continue}let
|
|
36
|
+
`),n=0;for(;n<e.length;){let r=e[n];if(!r.trim()){n++;continue}let o=r.match(/^\s*(```+|~~~+)\s*([\w+-]*)/);if(o){let p=[];for(n++;n<e.length&&!e[n].trim().startsWith(o[1]);)p.push(e[n++]);n++;let d=f(i,"pre"),u=f(i,"code");o[2]&&(u.dataset.lang=o[2]),u.textContent=p.join(`
|
|
37
|
+
`),d.appendChild(u),t.appendChild(d);continue}let a=r.match(/^(#{1,6})\s+(.*)$/);if(a){let p=`h${Math.min(6,a[1].length+2)}`,d=f(i,p);k(i,a[2],d),t.appendChild(d),n++;continue}if(/^\s*([-*_])(\s*\1){2,}\s*$/.test(r)){t.appendChild(f(i,"hr")),n++;continue}if(r.includes("|")&&n+1<e.length&&dt(e[n+1])){let p=f(i,"div","table"),d=f(i,"table"),u=f(i,"thead"),m=f(i,"tr");for(let x of gt(r)){let y=f(i,"th");k(i,x,y),m.appendChild(y)}u.appendChild(m),d.appendChild(u);let w=f(i,"tbody");for(n+=2;n<e.length&&e[n].includes("|")&&e[n].trim();){let x=f(i,"tr");for(let y of gt(e[n])){let M=f(i,"td");k(i,y,M),x.appendChild(M)}w.appendChild(x),n++}d.appendChild(w),p.appendChild(d),t.appendChild(p);continue}if(/^\s*>/.test(r)){let p=[];for(;n<e.length&&/^\s*>/.test(e[n]);)p.push(e[n++].replace(/^\s*>\s?/,""));let d=f(i,"blockquote");d.appendChild(E(i,p.join(`
|
|
38
|
+
`))),t.appendChild(d);continue}let l=r.match(/^(\s*)([-*+]|\d+[.)])\s+(.*)$/);if(l){let p=/\d/.test(l[2]),d=f(i,p?"ol":"ul");p&&parseInt(l[2],10)!==1&&d.setAttribute("start",String(parseInt(l[2],10)));let u=l[1].length;for(;n<e.length;){let m=e[n].match(/^(\s*)([-*+]|\d+[.)])\s+(.*)$/);if(!m||m[1].length<u||/\d/.test(m[2])!==p)break;if(m[1].length>u){let x=[];for(;n<e.length&&/^\s+/.test(e[n])&&e[n].match(/^(\s*)/)[1].length>u;)x.push(e[n++].slice(u+2));d.lastElementChild?.appendChild(E(i,x.join(`
|
|
39
|
+
`)));continue}let w=f(i,"li");k(i,m[3],w),d.appendChild(w),n++}t.appendChild(d);continue}let c=[];for(;n<e.length&&e[n].trim()&&!/^\s*(```|~~~|#{1,6}\s|>|([-*+]|\d+[.)])\s)/.test(e[n])&&!(e[n].includes("|")&&n+1<e.length&&dt(e[n+1]));)c.push(e[n++]);c.length||c.push(e[n++]);let g=f(i,"p");c.forEach((p,d)=>{d&&g.appendChild(f(i,"br")),k(i,p,g)}),t.appendChild(g)}return t}var pt=`
|
|
11
40
|
:host {
|
|
12
41
|
--dw-accent: #5446e8;
|
|
13
42
|
--dw-accent-contrast: #fff;
|
|
@@ -37,6 +66,7 @@
|
|
|
37
66
|
}
|
|
38
67
|
* { box-sizing: border-box; }
|
|
39
68
|
button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; padding: 0; }
|
|
69
|
+
[hidden] { display: none !important; }
|
|
40
70
|
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
|
|
41
71
|
|
|
42
72
|
/* ---------- launcher ---------- */
|
|
@@ -82,6 +112,8 @@ button { font: inherit; color: inherit; background: none; border: 0; cursor: poi
|
|
|
82
112
|
@media (max-width: 520px) {
|
|
83
113
|
:host(:not([data-mode="inline"])) .panel { inset: 0; width: 100vw; height: 100dvh; border-radius: 0; border: 0; }
|
|
84
114
|
:host([data-open]:not([data-mode="inline"])) .launcher { display: none; }
|
|
115
|
+
:host(:not([data-mode="inline"])) .head { padding-top: max(14px, env(safe-area-inset-top)); }
|
|
116
|
+
:host(:not([data-mode="inline"])) .composer { padding-bottom: max(12px, env(safe-area-inset-bottom)); }
|
|
85
117
|
}
|
|
86
118
|
|
|
87
119
|
/* ---------- header ---------- */
|
|
@@ -99,7 +131,7 @@ button { font: inherit; color: inherit; background: none; border: 0; cursor: poi
|
|
|
99
131
|
.who { flex: 1; min-width: 0; }
|
|
100
132
|
.title { font-weight: 650; font-size: 15px; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
101
133
|
.subtitle { font-size: 12px; color: var(--dw-muted); display: flex; align-items: center; gap: 6px; margin-top: 2px; }
|
|
102
|
-
.dot { width: 7px; height: 7px; border-radius: 50%; background: #22c58b; box-shadow: 0 0 0 3px color-mix(in srgb, #22c58b 22%, transparent); }
|
|
134
|
+
.dot { flex: none; width: 7px; height: 7px; border-radius: 50%; background: #22c58b; box-shadow: 0 0 0 3px color-mix(in srgb, #22c58b 22%, transparent); }
|
|
103
135
|
.agent-select {
|
|
104
136
|
font: inherit; font-size: 12px; color: var(--dw-muted); background: transparent; border: 0;
|
|
105
137
|
padding: 0 14px 0 0; margin: 0; max-width: 170px; cursor: pointer; appearance: none; field-sizing: content; text-overflow: ellipsis;
|
|
@@ -200,6 +232,46 @@ details > summary svg.ic { width: 14px; height: 14px; flex: none; }
|
|
|
200
232
|
.typing i:nth-child(2) { animation-delay: .15s; } .typing i:nth-child(3) { animation-delay: .3s; }
|
|
201
233
|
@keyframes bounce { 0%, 60%, 100% { transform: none; opacity: .35; } 30% { transform: translateY(-4px); opacity: 1; } }
|
|
202
234
|
|
|
235
|
+
/* page actions */
|
|
236
|
+
.actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 8px; }
|
|
237
|
+
.md[hidden] + .actions { margin-top: 0; }
|
|
238
|
+
.action {
|
|
239
|
+
display: inline-flex; align-items: center; gap: 6px; max-width: 100%; padding: 4px 9px 4px 8px; border-radius: 999px;
|
|
240
|
+
border: 1px solid var(--dw-border); background: var(--dw-surface); font-size: 12px; color: var(--dw-muted);
|
|
241
|
+
}
|
|
242
|
+
.action svg.ic { width: 13px; height: 13px; flex: none; color: var(--dw-accent); }
|
|
243
|
+
.action-name { font-family: var(--dw-mono); font-size: 11.5px; color: var(--dw-fg); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
244
|
+
.action-state { font-size: 11px; flex: none; }
|
|
245
|
+
.action[data-status="done"] .action-state { color: #13a06f; }
|
|
246
|
+
.action[data-status="awaiting-confirmation"] { border-color: color-mix(in srgb, #d98a00 45%, transparent); }
|
|
247
|
+
.action[data-status="awaiting-confirmation"] .action-state { color: #b06f00; }
|
|
248
|
+
.action[data-status="denied"] .action-state, .action[data-status="error"] .action-state { color: #c2334f; }
|
|
249
|
+
.notice { margin: -6px 0 16px; font-size: 12px; color: var(--dw-muted); text-align: center; }
|
|
250
|
+
.confirm-backdrop {
|
|
251
|
+
position: absolute; inset: 0; z-index: 2; display: flex; align-items: flex-end; justify-content: center; padding: 12px;
|
|
252
|
+
background: color-mix(in srgb, var(--dw-fg) 28%, transparent); animation: rise .18s ease both;
|
|
253
|
+
}
|
|
254
|
+
.confirm {
|
|
255
|
+
width: 100%; max-height: 100%; overflow: auto; background: var(--dw-bg); color: var(--dw-fg);
|
|
256
|
+
border: 1px solid var(--dw-border); border-radius: 16px; padding: 16px; box-shadow: var(--dw-shadow);
|
|
257
|
+
}
|
|
258
|
+
.confirm h3 { margin: 0 0 10px; font-size: 15px; font-weight: 650; }
|
|
259
|
+
.confirm-action { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
|
|
260
|
+
.confirm-action code { font-family: var(--dw-mono); font-size: 12.5px; background: var(--dw-surface); padding: 2px 6px; border-radius: 6px; }
|
|
261
|
+
.sens { font-size: 11px; padding: 1px 7px; border-radius: 999px; border: 1px solid var(--dw-border); color: var(--dw-muted); }
|
|
262
|
+
.sens[data-level="destructive"] { color: #c2334f; border-color: color-mix(in srgb, #c2334f 40%, transparent); }
|
|
263
|
+
.confirm-text { margin: 8px 0 0; font-size: 13.5px; line-height: 1.5; color: var(--dw-muted); }
|
|
264
|
+
.confirm-warn { margin: 8px 0 0; font-size: 13px; font-weight: 600; color: #c2334f; }
|
|
265
|
+
.confirm-args {
|
|
266
|
+
margin: 10px 0 0; font-family: var(--dw-mono); font-size: 11.5px; line-height: 1.5; background: var(--dw-surface);
|
|
267
|
+
border: 1px solid var(--dw-border); border-radius: 8px; padding: 8px; max-height: 160px; overflow: auto; white-space: pre-wrap; overflow-wrap: anywhere;
|
|
268
|
+
}
|
|
269
|
+
.confirm-buttons { display: flex; justify-content: flex-end; gap: 8px; margin-top: 14px; }
|
|
270
|
+
.btn { font: inherit; font-size: 13.5px; font-weight: 600; padding: 8px 14px; border-radius: 10px; border: 1px solid var(--dw-border); background: var(--dw-bg); color: var(--dw-fg); min-height: 38px; }
|
|
271
|
+
.btn.allow { background: var(--dw-accent); border-color: var(--dw-accent); color: var(--dw-accent-contrast); }
|
|
272
|
+
.btn.allow.danger { background: #c2334f; border-color: #c2334f; color: #fff; }
|
|
273
|
+
.btn:focus-visible { outline: 3px solid color-mix(in srgb, var(--dw-accent) 45%, transparent); outline-offset: 2px; }
|
|
274
|
+
|
|
203
275
|
/* ---------- composer ---------- */
|
|
204
276
|
.composer { padding: 10px 12px 12px; border-top: 1px solid var(--dw-border); background: var(--dw-bg); }
|
|
205
277
|
.box {
|
|
@@ -209,7 +281,7 @@ details > summary svg.ic { width: 14px; height: 14px; flex: none; }
|
|
|
209
281
|
.box:focus-within { border-color: var(--dw-accent); box-shadow: 0 0 0 3px color-mix(in srgb, var(--dw-accent) 16%, transparent); }
|
|
210
282
|
textarea {
|
|
211
283
|
flex: 1; resize: none; border: 0; outline: 0; background: transparent; color: var(--dw-fg);
|
|
212
|
-
font: inherit; font-size:
|
|
284
|
+
font: inherit; font-size: 16px; line-height: 1.45; max-height: 140px; padding: 5px 0; min-height: 34px;
|
|
213
285
|
}
|
|
214
286
|
textarea::placeholder { color: var(--dw-muted); }
|
|
215
287
|
.send {
|
|
@@ -224,9 +296,13 @@ textarea::placeholder { color: var(--dw-muted); }
|
|
|
224
296
|
.foot a:hover { color: var(--dw-accent); }
|
|
225
297
|
.challenge:empty { display: none; }
|
|
226
298
|
.challenge { display: flex; justify-content: center; padding: 8px 0; }
|
|
299
|
+
/* iOS zooms into any focused field under 16px; keep touch-device fields at 16px. */
|
|
300
|
+
@media (pointer: coarse) {
|
|
301
|
+
.agent-select { font-size: 16px; max-width: 200px; }
|
|
302
|
+
}
|
|
227
303
|
@media (prefers-reduced-motion: reduce) { *, *::before, *::after { animation: none !important; transition: none !important; } }
|
|
228
|
-
`;var
|
|
229
|
-
<style>${
|
|
304
|
+
`;var mt=["show-reasoning","show-tool-calls","allow-agent-switch","open","persist","hide-branding","launcher-avatar"],ht=["endpoint","agent","title","subtitle","greeting","intro","placeholder","suggestions","avatar","position","mode","theme","accent-color","locale","gateway-url","gateway-token","width","height","z-index",...mt],ut=i=>i.replace(/-([a-z])/g,(s,t)=>t.toUpperCase()),Lt=i=>i!==null&&!/^(false|0|off|no)$/i.test(i),ft=()=>{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{}}},Rt=null;function $t(){return Rt??(Rt=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,L=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",q());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 ht}get config(){let t={endpoint:"/api/dewee"};for(let e of ht){let n=this.getAttribute(e);n!==null&&(mt.includes(e)?t[ut(e)]=Lt(n):e==="suggestions"?t.suggestions=n.trim().startsWith("[")?Ht(n,[]):n.split("|").map(r=>r.trim()).filter(Boolean):e==="z-index"?t.zIndex=Number(n):t[ut(e)]=n)}return{...t,...this.overrides,...this.hooks}}configure(t){let{actions:e,confirm:n,getPageContext:r,...o}=t,a=l=>Object.prototype.hasOwnProperty.call(t,l);a("actions")&&this.setPropActions(e??[]),a("confirm")&&(this.hooks.confirm=n),a("getPageContext")&&(this.hooks.getPageContext=r),Object.keys(o).length&&(this.overrides={...this.overrides,...o},this.els&&this.applyConfig())}registerActions(t){this.registry.register(t)}unregisterAction(t){return this.propActionNames.delete(t),this.registry.unregister(t)}get actionNames(){return this.registry.names()}setPropActions(t){let e=new Set(t.map(n=>n.name));for(let n of this.propActionNames)e.has(n)||this.registry.unregister(n);t.length&&this.registry.register(t),this.propActionNames=e}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 e=t.trim();if(!e||this.running)return;this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),await this.activate(),this.els.input.value="",this.autosize();let n={message:e,hidden:!1};for(let r=0;n;r++){let o=await this.runTurn(n.message,n.hidden);if(n=null,o.status!=="done"||o.stopped||!this.registry.size)break;let{calls:a}=H(o.content);if(!a.length)break;o.actions=a.map(g=>({id:g.id,name:g.name,args:g.ok?g.args:void 0,status:"pending"}));let l=this.config.maxActionRounds??5;if(r>=l){for(let g of o.actions)Object.assign(g,{status:"error",error:"Automatic action limit reached"});this.updateMessage(o),this.showNotice(this.strings.actionLimit(l));break}this.updateMessage(o);let c=await this.runActions(o,a);c&&(n={message:et(c,this.server?.maxMessageLength??4e3),hidden:!0})}}async runTurn(t,e){this.pushMessage({role:"user",content:t,hidden:e});let n={role:"assistant",content:"",status:"streaming",startedAt:Date.now()};this.pushMessage(n),this.setRunning(new AbortController),this.emit("dewee:send",{message:t,agent:this.agentId,conversationId:this.conversationId,auto:e||void 0});try{await this.client().chat(this.chatBody(t),r=>this.onStreamEvent(n,r),this.running.signal),n.status==="streaming"&&(n.status="done")}catch(r){r.name==="AbortError"?(n.status="done",n.stopped=!0,n.content||(n.content=`_${this.strings.stopped}_`)):(n.status="error",this.showError(n,r))}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(t){let e={message:t,agent:this.agentId,conversationId:this.conversationId};if(this.registry.size){e.actions=this.registry.manifest();let r=this.getAck();r&&(e.actionsHash=r)}let n=this.pageContext();return n!==void 0&&(e.pageContext=n),e}pageContext(){let t=this.hooks.getPageContext;if(t)try{let e=t();if(e==null)return;let n=new TextEncoder().encode(JSON.stringify(e)).length;return n<=C.maxPageContextBytes?e:(console.warn(`[dewee-webchat] getPageContext() returned ${n} bytes; the limit is ${C.maxPageContextBytes}. Context not sent.`),{truncated:!0})}catch(e){console.warn("[dewee-webchat] getPageContext() failed:",e);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,e){let n=new AbortController;this.setRunning(n);let r=[],o={agent:this.agentId,conversationId:this.conversationId};try{for(let[a,l]of e.entries()){let c=t.actions[a],g=l.ok?this.registry.get(l.name)?.sensitivity:void 0,p=l.ok?l.args:void 0;this.emit("dewee:action",{phase:"start",id:l.id,name:l.name,sensitivity:g,args:p,...o});let d=await ot(l,{registry:this.registry,confirm:(u,m)=>this.confirmAction(u,m,n.signal),signal:n.signal,timeoutMs:this.config.actionTimeoutMs,...o,onStatus:u=>{c.status=u,this.updateMessage(t)}});d.error&&(c.error=d.error),this.updateMessage(t),r.push(d),this.emit("dewee:action",{phase:"result",id:d.id,name:d.name,sensitivity:g,args:p,status:d.status,result:d.result,error:d.error,...o})}}finally{this.setRunning(null)}return n.signal.aborted?null:r}confirmAction(t,e,n){return this.hooks.confirm?this.hooks.confirm(t,e):(this.config.mode!=="inline"&&!this.hasAttribute("data-open")&&this.open(),ct(this.els.panel,this.strings,t,e,n))}showNotice(t){let e=document.createElement("div");e.className="notice",e.setAttribute("role","status"),e.textContent=t,this.els.log.appendChild(e),this.scrollToBottom(!0)}stop(){this.running?.abort()}newConversation(){this.stop(),this.conversationId=ft(),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,e){this.dispatchEvent(new CustomEvent(t,{detail:e,bubbles:!0,composed:!0}))}client(){let t=this.config,e=[t.endpoint,t.gatewayUrl,t.gatewayToken].join("|");return(!this.api||e!==this.apiKey)&&(this.apiKey=e,this.api=new S({endpoint:t.endpoint,gatewayUrl:t.gatewayUrl,gatewayToken:t.gatewayToken,turnstile:n=>this.challenge(n)})),this.api}convKey(){return`dewee-webchat:conv:${this.config.endpoint}:${this.config.gatewayUrl||""}:${this.agentId}`}applyTheme(){let t=this.config.theme||"light",e=t==="dark"||t==="auto"&&!!this.mql?.matches;this.setAttribute("data-theme",e?"dark":"light")}applyConfig(){let t=this.config;this.strings=q(t.locale);let e=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 n=(o,a)=>a!==void 0&&a!==""?this.style.setProperty(o,String(a)):this.style.removeProperty(o);n("--dw-accent",t.accentColor),n("--dw-width",t.width),n("--dw-height",t.height),n("--dw-z",t.zIndex);let r=this.els;if(r.title.textContent=t.title||e.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||e.title).trim().charAt(0).toUpperCase();if(r.launcher.innerHTML=t.avatar&&t.launcherAvatar?"":b.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",e.open),r.close.setAttribute("aria-label",e.close),r.close.title=e.close,r.newChat.setAttribute("aria-label",e.newChat),r.newChat.title=e.newChat,r.input.placeholder=t.placeholder||e.placeholder,r.foot.hidden=!!t.hideBranding,r.foot.querySelector(".by").textContent=e.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>${pt}</style>
|
|
230
306
|
<button class="launcher" part="launcher" aria-expanded="false" aria-haspopup="dialog"></button>
|
|
231
307
|
<section class="panel" part="panel" role="dialog" aria-label="Chat">
|
|
232
308
|
<header class="head" part="header">
|
|
@@ -235,8 +311,8 @@ textarea::placeholder { color: var(--dw-muted); }
|
|
|
235
311
|
<div class="title"></div>
|
|
236
312
|
<div class="subtitle"><span class="dot"></span><span class="status"></span><select class="agent-select" hidden></select></div>
|
|
237
313
|
</div>
|
|
238
|
-
<button class="icon-btn new">${
|
|
239
|
-
<button class="icon-btn close">${
|
|
314
|
+
<button class="icon-btn new">${b.newChat}</button>
|
|
315
|
+
<button class="icon-btn close">${b.close}</button>
|
|
240
316
|
</header>
|
|
241
317
|
<div class="log" part="log" role="log" aria-live="polite"></div>
|
|
242
318
|
<div class="challenge"><slot name="challenge"></slot></div>
|
|
@@ -247,6 +323,7 @@ textarea::placeholder { color: var(--dw-muted); }
|
|
|
247
323
|
</div>
|
|
248
324
|
<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>
|
|
249
325
|
</form>
|
|
250
|
-
</section>`;let
|
|
326
|
+
</section>`;let t=n=>this.root.querySelector(n);this.els={launcher:t(".launcher"),panel:t(".panel"),log:t(".log"),title:t(".title"),subtitle:t(".subtitle"),status:t(".status"),avatar:t(".avatar"),select:t(".agent-select"),input:t("textarea"),send:t(".send"),newChat:t(".new"),close:t(".close"),foot:t(".foot")};let e=this.els;e.launcher.addEventListener("click",()=>this.toggle()),e.close.addEventListener("click",()=>this.close()),e.log.addEventListener("scroll",()=>{this.following=this.nearBottom()},{passive:!0}),e.newChat.addEventListener("click",()=>this.newConversation()),e.select.addEventListener("change",()=>this.switchAgent(e.select.value)),t("form").addEventListener("submit",n=>{n.preventDefault(),this.running?this.stop():this.send(e.input.value)}),e.input.addEventListener("keydown",n=>{n.key==="Enter"&&!n.shiftKey&&!n.isComposing&&n.keyCode!==229&&(n.preventDefault(),this.running||this.send(e.input.value))}),e.input.addEventListener("input",()=>{this.autosize(),this.updateSendButton()}),e.panel.addEventListener("keydown",n=>{n.key==="Escape"&&this.close()})}autosize(){let t=this.els.input;t.style.height="auto",t.style.height=Math.min(t.scrollHeight,140)+"px"}updateSendButton(){let t=this.els.send;t.innerHTML=this.running?b.stop:b.send,t.setAttribute("aria-label",this.running?this.strings.stop:this.strings.send),t.title=t.getAttribute("aria-label"),t.disabled=!this.running&&!this.els.input.value.trim()}setRunning(t){this.running=t,this.updateSendButton()}renderSubtitle(){let t=this.els,e=this.config,n=this.server?.agents??[],r=e.allowAgentSwitch!==!1&&!!this.server?.allowAgentSwitch&&n.length>1;t.select.hidden=!r,t.status.hidden=r,r&&(t.select.replaceChildren(...n.map(a=>new Option(a.name||a.id,a.id,!1,a.id===this.agentId))),t.select.setAttribute("aria-label","Agent"));let o=n.find(a=>a.id===this.agentId);t.status.textContent=e.subtitle||(o?.name&&o.name!==e.title?`${this.strings.online} \xB7 ${o.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 t=this.config.agent,e=n=>!!n&&(this.server.agents.length===0||this.server.agents.some(r=>r.id===n));this.agentId=e(t)?t:this.server.defaultAgent||this.server.agents[0]?.id||t||"",await this.loadConversation()}catch(t){this.activated=!1,this.renderLog(),this.showError(null,t)}this.renderSubtitle(),this.emit("dewee:ready",{agent:this.agentId,config:this.server})}}async switchAgent(t){t!==this.agentId&&(this.stop(),this.agentId=t,this.renderSubtitle(),await this.loadConversation())}async loadConversation(){let t=this.config.persist!==!1,e=t?T.get(this.convKey()):null;if(this.conversationId=e||ft(),t&&!e&&T.set(this.convKey(),this.conversationId),this.messages=[],this.renderLog(),!!e)try{let n=await this.client().history(this.agentId,this.conversationId);this.messages=_t(n.map(r=>({...r,status:"done"}))),this.renderLog()}catch{}}renderLog(){let t=this.els.log;t.replaceChildren(),this.messages.length||t.appendChild(this.renderWelcome());for(let e of this.messages)t.appendChild(this.renderMessage(e));t.scrollTop=t.scrollHeight}renderWelcome(){let t=this.config,e=this.strings,n=document.createElement("div");n.className="welcome";let r=document.createElement("h2");r.textContent=t.greeting||e.greeting;let o=document.createElement("p");if(o.textContent=t.intro||e.greetingBody,n.append(r,o),t.suggestions?.length){let a=document.createElement("div");a.className="suggestions";for(let l of t.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(t){this.messages.length||this.els.log.replaceChildren(),this.messages.push(t),this.els.log.appendChild(this.renderMessage(t)),this.scrollToBottom(!0)}renderMessage(t){let e=document.createElement("div");e.className=`msg ${t.role}${t.status==="error"?" error":""}`,e.hidden=!!t.hidden;let n=document.createElement("div");n.className="bubble",e.appendChild(n);let r=document.createElement("div");r.className="trace";let o=document.createElement("div");o.className=t.role==="assistant"?"md":"";let a=document.createElement("div");return a.className="actions",a.hidden=!0,t.role==="assistant"&&n.appendChild(r),n.appendChild(o),t.role==="assistant"&&n.appendChild(a),t.view={root:e,trace:r,md:o,tools:new Map,actions:a},this.updateMessage(t),e}updateMessage(t){let e=t.view;if(!e)return;let n=this.config;if(t.role==="user"){e.md.textContent=t.content;return}if(e.root.classList.toggle("error",t.status==="error"),n.showReasoning!==!1&&t.thinking){e.thinking||(e.thinking=document.createElement("details"),e.thinking.className="thinking",e.thinking.innerHTML='<summary></summary><div class="thinking-body"></div>',e.trace.prepend(e.thinking));let a=t.status==="streaming"&&!t.thinkingMs,l=a?this.strings.thinking:t.thinkingMs?this.strings.thoughtFor(Math.max(1,Math.round(t.thinkingMs/1e3))):this.strings.reasoning,c=e.thinking.querySelector("summary");c.innerHTML=`${a?'<span class="spin"></span>':b.brain}<span></span>${b.down.replace("<svg",'<svg class="chev"')}`,c.querySelector("span:not(.spin)").textContent=l,e.thinking.querySelector(".thinking-body").textContent=t.thinking}else e.thinking&&(e.thinking.remove(),e.thinking=void 0);if(n.showToolCalls!==!1)for(let a of t.toolCalls??[])this.renderTool(e,a);else e.tools.forEach(a=>a.remove()),e.tools.clear();e.trace.hidden=!e.trace.childElementCount;let r=this.registry.size||t.actions?X(t.content):t.content,o=t.status==="streaming"&&!r;e.md.hidden=!o&&!r&&!!t.actions?.length,o?e.md.innerHTML=`<span class="typing" aria-label="${this.strings.thinking}"><i></i><i></i><i></i></span>`:(e.md.replaceChildren(E(document,r)),e.md.classList.toggle("cursor",t.status==="streaming")),this.renderActions(e,t.actions??[])}renderActions(t,e){t.actions.hidden=!e.length,t.actions.replaceChildren(...e.map(n=>{let r=document.createElement("div");r.className="action",r.dataset.status=n.status;let o=n.status==="running"||n.status==="awaiting-confirmation";r.innerHTML=`${o?'<span class="spin"></span>':b.action}<span class="action-name"></span><span class="action-state"></span>`,r.querySelector(".action-name").textContent=n.name||"?",r.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(`
|
|
327
|
+
`);return a&&(r.title=a),r}))}renderTool(t,e){let n=t.tools.get(e.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>${b.down.replace("<svg",'<svg class="chev"')}</summary><div class="tool-body"></div>`,t.tools.set(e.id,n),t.trace.appendChild(n)),n.dataset.status=e.status,n.querySelector(".lead").innerHTML=e.status==="running"?'<span class="spin"></span>':b.tool;let r=n.querySelector(".tool-name");r.textContent=It(e.name),r.setAttribute("title",e.name),n.querySelector(".tool-state").textContent=e.status==="running"?this.strings.toolRunning:e.status==="error"?this.strings.toolError:this.strings.toolDone;let o=n.querySelector(".tool-body");o.replaceChildren();let a=(l,c)=>{if(c==null||c==="")return;let g=document.createElement("div");g.className="label",g.textContent=l;let p=document.createElement("pre");p.textContent=typeof c=="string"?Bt(c):JSON.stringify(c,null,2),o.append(g,p)};a(this.strings.args,e.arguments),a(this.strings.result,e.result)}onStreamEvent(t,e){switch(e.type){case"start":e.actionsHash&&(t.actionsHash=e.actionsHash),e.conversationId&&e.conversationId!==this.conversationId&&(this.conversationId=e.conversationId,this.config.persist!==!1&&T.set(this.convKey(),e.conversationId));break;case"thinking":t.thinking=(t.thinking||"")+e.text;break;case"delta":this.finishThinking(t),t.content+=e.text;break;case"tool_call":this.finishThinking(t),(t.toolCalls??(t.toolCalls=[])).push({id:e.id,name:e.name,arguments:e.arguments,status:"running"});break;case"tool_result":{let n=t.toolCalls?.find(r=>r.id===e.id)??(t.toolCalls??(t.toolCalls=[]))[t.toolCalls.push({id:e.id,name:e.name,status:"running"})-1];n.status=e.isError?"error":"done",n.result=e.result,n.isError=e.isError;break}case"done":this.finishThinking(t),e.content&&e.content.length>=t.content.length&&(t.content=e.content),t.status="done";break;case"error":t.status="error",this.showError(t,new v(e.message,500,e.code));break}this.scheduleUpdate(t)}scheduleUpdate(t){this.pendingFrame||(this.pendingFrame=requestAnimationFrame(()=>{this.pendingFrame=0,this.updateMessage(t),this.following&&this.scrollToBottom(!0)}))}finishThinking(t){t.thinking&&!t.thinkingMs&&t.startedAt&&(t.thinkingMs=Date.now()-t.startedAt)}nearBottom(){let t=this.els.log;return t.scrollHeight-t.scrollTop-t.clientHeight<96}scrollToBottom(t=!1){let e=this.els.log;(t||this.nearBottom())&&(e.scrollTop=e.scrollHeight,this.following=!0)}showError(t,e){let n=e.message||this.strings.errorGeneric;if(this.emit("dewee:error",{message:n,code:e.code}),t){t.content=t.content?`${t.content}
|
|
251
328
|
|
|
252
|
-
> \u26A0\uFE0F ${n}`:`\u26A0\uFE0F ${n}`,
|
|
329
|
+
> \u26A0\uFE0F ${n}`:`\u26A0\uFE0F ${n}`,t.status="error",this.updateMessage(t);return}let r=document.createElement("div");r.className="msg error",r.innerHTML='<div class="bubble"></div>',r.firstElementChild.textContent=`\u26A0\uFE0F ${n}`,this.els.log.appendChild(r)}async challenge(t){await $t();let e=document.createElement("div");e.slot="challenge",this.appendChild(e);try{return await new Promise((n,r)=>{window.turnstile.render(e,{sitekey:t,appearance:"interaction-only",theme:this.getAttribute("data-theme")==="dark"?"dark":"light",callback:n,"error-callback":()=>r(new v("Verification failed",403,"turnstile_failed"))})})}finally{e.remove()}}};function _t(i){return i.forEach((s,t)=>{if(s.role==="user"){s.content=j(s.content),B(s.content)&&(s.hidden=!0);return}if(!s.content.includes("```dewee-action"))return;let{calls:e}=H(s.content);if(!e.length)return;let n=i[t+1],r=n?.role==="user"?j(n.content):"",o=B(r)?tt(r):[];s.actions=e.map(a=>{let l=o.find(g=>g.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}function Ht(i,s){try{return JSON.parse(i)}catch{return s}}function Bt(i){let s=i.trim();if(!/^[[{]/.test(s))return i;try{return JSON.stringify(JSON.parse(s),null,2)}catch{return i}}function V(i="dewee-chat"){typeof window>"u"||!window.customElements||customElements.get(i)||customElements.define(i,class extends L{})}function Ot(i={},s){V();let t=document.createElement("dewee-chat");return t.configure(i),((typeof s=="string"?document.querySelector(s):s)??document.body).appendChild(t),t}V();var zt=document.currentScript,N=zt?.dataset;if(N&&N.endpoint&&N.autoMount!=="false"){let i=()=>{let s=document.createElement("dewee-chat");for(let[t,e]of Object.entries(N))t==="autoMount"||e===void 0||s.setAttribute(t.replace(/[A-Z]/g,n=>"-"+n.toLowerCase()),e);document.body.appendChild(s)};document.readyState==="loading"?document.addEventListener("DOMContentLoaded",i):i()}window.DeweeWebchat=K;})();
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,43 @@
|
|
|
1
|
-
import { P as PublicConfig, S as SessionResponse, H as HistoryMessage, C as ChatStreamEvent } from './protocol-
|
|
2
|
-
export { A as AgentInfo, T as ToolCallView } from './protocol-
|
|
1
|
+
import { b as ActionSensitivity, P as PublicConfig, S as SessionResponse, H as HistoryMessage, c as ChatRequestBody, C as ChatStreamEvent } from './protocol-B72Ry-fY.js';
|
|
2
|
+
export { a as ActionManifestEntry, A as AgentInfo, T as ToolCallView } from './protocol-B72Ry-fY.js';
|
|
3
|
+
|
|
4
|
+
type ActionResultStatus = "ok" | "denied" | "error";
|
|
5
|
+
interface ActionResult {
|
|
6
|
+
id: string;
|
|
7
|
+
name: string;
|
|
8
|
+
status: ActionResultStatus;
|
|
9
|
+
result?: unknown;
|
|
10
|
+
error?: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
type JsonSchema = Record<string, unknown>;
|
|
14
|
+
|
|
15
|
+
interface PageActionContext {
|
|
16
|
+
/** Id the agent gave this call. */
|
|
17
|
+
callId: string;
|
|
18
|
+
conversationId: string;
|
|
19
|
+
agent: string;
|
|
20
|
+
/** Aborted when the visitor stops the run, starts a new conversation, or the handler times out. */
|
|
21
|
+
signal: AbortSignal;
|
|
22
|
+
}
|
|
23
|
+
interface PageAction<Args = any> {
|
|
24
|
+
/** `^[a-z][a-z0-9_.-]{0,63}$` */
|
|
25
|
+
name: string;
|
|
26
|
+
/** What the action does, written for the agent. */
|
|
27
|
+
description: string;
|
|
28
|
+
/** JSON Schema subset for `args` (an object schema). */
|
|
29
|
+
parameters?: JsonSchema;
|
|
30
|
+
sensitivity: ActionSensitivity;
|
|
31
|
+
/** Runs in the page. Must return JSON-serializable data. Agent args are untrusted: validate before acting. */
|
|
32
|
+
handler: (args: Args, ctx: PageActionContext) => unknown | Promise<unknown>;
|
|
33
|
+
}
|
|
34
|
+
/** An action as shown to the confirm hook (no handler). */
|
|
35
|
+
type PageActionInfo = Omit<PageAction, "handler">;
|
|
36
|
+
/** Host-owned approval for `mutate`/`destructive` calls. Only a resolved `true` approves. */
|
|
37
|
+
type ActionConfirmHook = (action: PageActionInfo & {
|
|
38
|
+
callId: string;
|
|
39
|
+
}, args: Record<string, unknown>) => boolean | Promise<boolean>;
|
|
40
|
+
type ActionCallStatus = "pending" | "awaiting-confirmation" | "running" | "done" | "denied" | "error";
|
|
3
41
|
|
|
4
42
|
interface DeweeChatConfig {
|
|
5
43
|
/** Backend base URL (the server handler). Default: "/api/dewee". */
|
|
@@ -40,6 +78,37 @@ interface DeweeChatConfig {
|
|
|
40
78
|
width?: string;
|
|
41
79
|
height?: string;
|
|
42
80
|
zIndex?: number;
|
|
81
|
+
/** Page actions the agent may invoke. Replaces the set previously passed through this option. */
|
|
82
|
+
actions?: PageAction[];
|
|
83
|
+
/** Approval for `mutate`/`destructive` actions. Default: the built-in confirm dialog. Only `true` approves. */
|
|
84
|
+
confirm?: ActionConfirmHook;
|
|
85
|
+
/** Small, host-redacted snapshot of page state sent with every message (max 4 KB as JSON). */
|
|
86
|
+
getPageContext?: () => unknown;
|
|
87
|
+
/** Automatic action rounds allowed per visitor message. Default 5. */
|
|
88
|
+
maxActionRounds?: number;
|
|
89
|
+
/** Per-handler timeout. Default 30000 ms. */
|
|
90
|
+
actionTimeoutMs?: number;
|
|
91
|
+
}
|
|
92
|
+
/** A page action call as shown in the transcript. */
|
|
93
|
+
interface ActionCallView {
|
|
94
|
+
id: string;
|
|
95
|
+
name: string;
|
|
96
|
+
args?: Record<string, unknown>;
|
|
97
|
+
status: ActionCallStatus;
|
|
98
|
+
error?: string;
|
|
99
|
+
}
|
|
100
|
+
/** `detail` of the `dewee:action` event (host telemetry). */
|
|
101
|
+
interface ActionEventDetail {
|
|
102
|
+
phase: "start" | "result";
|
|
103
|
+
id: string;
|
|
104
|
+
name: string;
|
|
105
|
+
sensitivity?: ActionSensitivity;
|
|
106
|
+
args?: Record<string, unknown>;
|
|
107
|
+
status?: ActionResultStatus;
|
|
108
|
+
result?: unknown;
|
|
109
|
+
error?: string;
|
|
110
|
+
agent: string;
|
|
111
|
+
conversationId: string;
|
|
43
112
|
}
|
|
44
113
|
declare const ElementBase: typeof HTMLElement;
|
|
45
114
|
declare class DeweeChatElement extends ElementBase {
|
|
@@ -56,17 +125,40 @@ declare class DeweeChatElement extends ElementBase {
|
|
|
56
125
|
private activated;
|
|
57
126
|
private strings;
|
|
58
127
|
private mql;
|
|
128
|
+
private registry;
|
|
129
|
+
private propActionNames;
|
|
130
|
+
private hooks;
|
|
131
|
+
private acks;
|
|
59
132
|
private els;
|
|
60
133
|
constructor();
|
|
61
134
|
/** Current effective configuration (attributes merged with `configure()` overrides). */
|
|
62
135
|
get config(): DeweeChatConfig;
|
|
63
136
|
/** Updates configuration at runtime (wins over attributes). */
|
|
64
137
|
configure(partial: Partial<DeweeChatConfig>): void;
|
|
138
|
+
/** Adds or replaces page actions the agent may invoke. Throws TypeError on an invalid definition. */
|
|
139
|
+
registerActions(actions: PageAction | PageAction[]): void;
|
|
140
|
+
/** Removes a page action. Returns false when it was not registered. */
|
|
141
|
+
unregisterAction(name: string): boolean;
|
|
142
|
+
/** Names of the currently registered page actions. */
|
|
143
|
+
get actionNames(): string[];
|
|
144
|
+
private setPropActions;
|
|
65
145
|
open(): void;
|
|
66
146
|
close(): void;
|
|
67
147
|
toggle(): void;
|
|
68
148
|
/** Sends a message programmatically (opens the widget first). */
|
|
69
149
|
send(text: string): Promise<void>;
|
|
150
|
+
/** One request/response with the agent. */
|
|
151
|
+
private runTurn;
|
|
152
|
+
private chatBody;
|
|
153
|
+
/** Host snapshot, dropped (with a warning) when it fails or exceeds the backend cap. */
|
|
154
|
+
private pageContext;
|
|
155
|
+
private ackKey;
|
|
156
|
+
private getAck;
|
|
157
|
+
private setAck;
|
|
158
|
+
/** Executes the calls of one answer in order. Resolves null when the visitor stopped the chain. */
|
|
159
|
+
private runActions;
|
|
160
|
+
private confirmAction;
|
|
161
|
+
private showNotice;
|
|
70
162
|
/** Stops the running reply. */
|
|
71
163
|
stop(): void;
|
|
72
164
|
/** Starts a fresh conversation with the current agent. */
|
|
@@ -94,6 +186,7 @@ declare class DeweeChatElement extends ElementBase {
|
|
|
94
186
|
private pushMessage;
|
|
95
187
|
private renderMessage;
|
|
96
188
|
private updateMessage;
|
|
189
|
+
private renderActions;
|
|
97
190
|
private renderTool;
|
|
98
191
|
private onStreamEvent;
|
|
99
192
|
private pendingFrame;
|
|
@@ -138,8 +231,7 @@ declare class ApiClient {
|
|
|
138
231
|
forgetSession(): void;
|
|
139
232
|
history(agent: string, conversationId: string): Promise<HistoryMessage[]>;
|
|
140
233
|
/** Sends a message and calls `onEvent` for every streamed event. Resolves when the run ends. */
|
|
141
|
-
chat(input: {
|
|
142
|
-
message: string;
|
|
234
|
+
chat(input: ChatRequestBody & {
|
|
143
235
|
agent: string;
|
|
144
236
|
conversationId: string;
|
|
145
237
|
}, onEvent: (e: ChatStreamEvent) => void, signal?: AbortSignal): Promise<void>;
|
|
@@ -158,4 +250,4 @@ declare global {
|
|
|
158
250
|
}
|
|
159
251
|
}
|
|
160
252
|
|
|
161
|
-
export { ApiClient, type ApiClientOptions, ApiError, ChatStreamEvent, type DeweeChatConfig, DeweeChatElement, HistoryMessage, PublicConfig, SessionResponse, defineDeweeChat, mount, renderMarkdown };
|
|
253
|
+
export { type ActionCallStatus, type ActionCallView, type ActionConfirmHook, type ActionEventDetail, type ActionResult, type ActionResultStatus, ActionSensitivity, ApiClient, type ApiClientOptions, ApiError, ChatRequestBody, ChatStreamEvent, type DeweeChatConfig, DeweeChatElement, HistoryMessage, type JsonSchema, type PageAction, type PageActionContext, type PageActionInfo, PublicConfig, SessionResponse, defineDeweeChat, mount, renderMarkdown };
|
package/dist/index.js
CHANGED
|
@@ -4,6 +4,7 @@ type ChatStreamEvent = {
|
|
|
4
4
|
runId?: string;
|
|
5
5
|
conversationId: string;
|
|
6
6
|
agent: string;
|
|
7
|
+
actionsHash?: string;
|
|
7
8
|
} | {
|
|
8
9
|
type: "thinking";
|
|
9
10
|
text: string;
|
|
@@ -67,5 +68,25 @@ interface HistoryMessage {
|
|
|
67
68
|
toolCalls?: ToolCallView[];
|
|
68
69
|
createdAt?: string;
|
|
69
70
|
}
|
|
71
|
+
/** How much an agent-invoked page action can change. `mutate`/`destructive` always need user approval. */
|
|
72
|
+
type ActionSensitivity = "read" | "navigate" | "mutate" | "destructive";
|
|
73
|
+
/** What the backend (and the agent) learns about a page action. Handlers never leave the browser. */
|
|
74
|
+
interface ActionManifestEntry {
|
|
75
|
+
name: string;
|
|
76
|
+
description: string;
|
|
77
|
+
/** JSON Schema subset describing `args` (object). */
|
|
78
|
+
parameters: Record<string, unknown>;
|
|
79
|
+
sensitivity: ActionSensitivity;
|
|
80
|
+
}
|
|
81
|
+
/** Body of `POST {basePath}/chat`. `actions`/`actionsHash`/`pageContext` are optional (page actions). */
|
|
82
|
+
interface ChatRequestBody {
|
|
83
|
+
message: string;
|
|
84
|
+
agent?: string;
|
|
85
|
+
conversationId?: string;
|
|
86
|
+
actions?: ActionManifestEntry[];
|
|
87
|
+
/** Hash from the `start` event of the last completed turn; the manifest is re-sent to the agent only when it differs. */
|
|
88
|
+
actionsHash?: string;
|
|
89
|
+
pageContext?: unknown;
|
|
90
|
+
}
|
|
70
91
|
|
|
71
|
-
export type { AgentInfo as A, ChatStreamEvent as C, HistoryMessage as H, PublicConfig as P, SessionResponse as S, ToolCallView as T };
|
|
92
|
+
export type { AgentInfo as A, ChatStreamEvent as C, HistoryMessage as H, PublicConfig as P, SessionResponse as S, ToolCallView as T, ActionManifestEntry as a, ActionSensitivity as b, ChatRequestBody as c };
|
package/dist/react.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { CSSProperties } from 'react';
|
|
3
|
-
import { DeweeChatConfig, DeweeChatElement } from './index.js';
|
|
4
|
-
|
|
3
|
+
import { DeweeChatConfig, ActionEventDetail, DeweeChatElement } from './index.js';
|
|
4
|
+
export { ActionConfirmHook, PageAction, PageActionContext } from './index.js';
|
|
5
|
+
import './protocol-B72Ry-fY.js';
|
|
5
6
|
|
|
6
7
|
interface DeweeChatProps extends Partial<DeweeChatConfig> {
|
|
7
8
|
className?: string;
|
|
@@ -12,6 +13,8 @@ interface DeweeChatProps extends Partial<DeweeChatConfig> {
|
|
|
12
13
|
onError?: (e: CustomEvent) => void;
|
|
13
14
|
onOpen?: (e: CustomEvent) => void;
|
|
14
15
|
onClose?: (e: CustomEvent) => void;
|
|
16
|
+
/** Page action telemetry (`dewee:action`, detail: ActionEventDetail). */
|
|
17
|
+
onAction?: (e: CustomEvent<ActionEventDetail>) => void;
|
|
15
18
|
}
|
|
16
19
|
declare const DeweeChat: react.ForwardRefExoticComponent<DeweeChatProps & react.RefAttributes<DeweeChatElement | null>>;
|
|
17
20
|
|
|
@@ -23,4 +26,4 @@ declare module "react" {
|
|
|
23
26
|
}
|
|
24
27
|
}
|
|
25
28
|
|
|
26
|
-
export { DeweeChat, DeweeChatConfig, DeweeChatElement, type DeweeChatProps, DeweeChat as default };
|
|
29
|
+
export { ActionEventDetail, DeweeChat, DeweeChatConfig, DeweeChatElement, type DeweeChatProps, DeweeChat as default };
|