@kilnai/widget 0.1.8 → 0.1.10
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/dist/widget.js +63 -11
- package/package.json +1 -1
package/dist/widget.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
(()=>{var{defineProperty:b,getOwnPropertyNames:m,getOwnPropertyDescriptor:v}=Object,y=Object.prototype.hasOwnProperty;function w(
|
|
1
|
+
(()=>{var{defineProperty:b,getOwnPropertyNames:m,getOwnPropertyDescriptor:v}=Object,y=Object.prototype.hasOwnProperty;function w(n){return this[n]}var S=(n)=>{var i=(g??=new WeakMap).get(n),t;if(i)return i;if(i=b({},"__esModule",{value:!0}),n&&typeof n==="object"||typeof n==="function"){for(var e of m(n))if(!y.call(i,e))b(i,e,{get:w.bind(n,e),enumerable:!(t=v(n,e))||t.enumerable})}return g.set(n,i),i},g;var W=(n)=>n;function C(n,i){this[n]=W.bind(null,i)}var $=(n,i)=>{for(var t in i)b(n,t,{get:i[t],enumerable:!0,configurable:!0,set:C.bind(i,t)})};var F={};$(F,{KilnWidget:()=>k});class h{ws=null;reconnectTimer=null;reconnectDelay=1000;maxReconnectDelay=30000;intentionalClose=!1;messageHandler=null;statusHandler=null;url;userId;constructor(n,i,t){let e=n.startsWith("https")?"wss":"ws",s=n.replace(/^https?:\/\//,"").replace(/^wss?:\/\//,""),o=`kiln_widget_${t}`;this.userId=sessionStorage.getItem(o)??crypto.randomUUID(),sessionStorage.setItem(o,this.userId),this.url=`${e}://${s}/apps/${i}/ws?widgetId=${t}&userId=${encodeURIComponent(this.userId)}`}connect(){this.intentionalClose=!1,this.setStatus("connecting");let n=new WebSocket(this.url);this.ws=n,n.onopen=()=>{this.reconnectDelay=1000,this.setStatus("connected")},n.onmessage=(i)=>{try{let t=JSON.parse(i.data);this.messageHandler?.(t)}catch{}},n.onerror=()=>this.setStatus("error"),n.onclose=()=>{if(this.ws=null,!this.intentionalClose)this.setStatus("disconnected"),this.scheduleReconnect()}}send(n){if(!this.ws||this.ws.readyState!==WebSocket.OPEN)return;let i={type:"message",content:n};this.ws.send(JSON.stringify(i))}onMessage(n){this.messageHandler=n}onStatusChange(n){this.statusHandler=n}disconnect(){if(this.intentionalClose=!0,this.reconnectTimer)clearTimeout(this.reconnectTimer),this.reconnectTimer=null;this.ws?.close(),this.ws=null,this.setStatus("disconnected")}get connected(){return this.ws?.readyState===WebSocket.OPEN}setStatus(n){this.statusHandler?.(n)}scheduleReconnect(){this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect()},this.reconnectDelay),this.reconnectDelay=Math.min(this.reconnectDelay*2,this.maxReconnectDelay)}}function f(n){let i=n==="dark";return`
|
|
2
2
|
:host {
|
|
3
|
-
--kiln-bg: ${
|
|
4
|
-
--kiln-bg-secondary: ${
|
|
5
|
-
--kiln-text: ${
|
|
6
|
-
--kiln-text-secondary: ${
|
|
7
|
-
--kiln-border: ${
|
|
3
|
+
--kiln-bg: ${i?"#1a1a2e":"#ffffff"};
|
|
4
|
+
--kiln-bg-secondary: ${i?"#2a2a3e":"#f0f0f0"};
|
|
5
|
+
--kiln-text: ${i?"#e8e8f0":"#1a1a1a"};
|
|
6
|
+
--kiln-text-secondary: ${i?"#a0a0b8":"#6b7280"};
|
|
7
|
+
--kiln-border: ${i?"#3a3a5c":"#e5e7eb"};
|
|
8
8
|
--kiln-accent: #1a1a2e;
|
|
9
9
|
--kiln-accent-text: #ffffff;
|
|
10
10
|
--kiln-user-bubble: #1a1a2e;
|
|
11
11
|
--kiln-user-text: #ffffff;
|
|
12
|
-
--kiln-assistant-bubble: ${
|
|
13
|
-
--kiln-assistant-text: ${
|
|
12
|
+
--kiln-assistant-bubble: ${i?"#2a2a3e":"#f0f0f0"};
|
|
13
|
+
--kiln-assistant-text: ${i?"#e8e8f0":"#1a1a1a"};
|
|
14
14
|
--kiln-shadow: 0 8px 32px rgba(0, 0, 0, 0.18);
|
|
15
15
|
--kiln-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
|
|
16
16
|
--kiln-radius: 16px;
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
--kiln-status-error: #ef4444;
|
|
21
21
|
}
|
|
22
22
|
|
|
23
|
-
${
|
|
23
|
+
${n==="auto"?`
|
|
24
24
|
@media (prefers-color-scheme: dark) {
|
|
25
25
|
:host {
|
|
26
26
|
--kiln-bg: #1a1a2e;
|
|
@@ -294,6 +294,45 @@
|
|
|
294
294
|
border: 1px solid #fca5a5;
|
|
295
295
|
}
|
|
296
296
|
|
|
297
|
+
/* Info message (amber, for budget exhaustion) */
|
|
298
|
+
.kiln-msg.info .kiln-bubble {
|
|
299
|
+
background: #fef3c7;
|
|
300
|
+
color: #92400e;
|
|
301
|
+
border: 1px solid #fcd34d;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/* Suggestion chips */
|
|
305
|
+
.kiln-suggestions {
|
|
306
|
+
display: flex;
|
|
307
|
+
flex-wrap: wrap;
|
|
308
|
+
gap: 6px;
|
|
309
|
+
padding: 4px 0;
|
|
310
|
+
align-self: flex-start;
|
|
311
|
+
max-width: 90%;
|
|
312
|
+
animation: kiln-msg-in 0.18s ease;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
.kiln-chip {
|
|
316
|
+
background: var(--kiln-bg-secondary);
|
|
317
|
+
color: var(--kiln-text);
|
|
318
|
+
border: 1px solid var(--kiln-border);
|
|
319
|
+
border-radius: 14px;
|
|
320
|
+
padding: 6px 12px;
|
|
321
|
+
font-size: 13px;
|
|
322
|
+
font-family: var(--kiln-font);
|
|
323
|
+
cursor: pointer;
|
|
324
|
+
transition: background 0.15s ease, border-color 0.15s ease;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.kiln-chip:hover {
|
|
328
|
+
border-color: var(--kiln-accent);
|
|
329
|
+
background: var(--kiln-bg);
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
.kiln-chip:active {
|
|
333
|
+
transform: scale(0.97);
|
|
334
|
+
}
|
|
335
|
+
|
|
297
336
|
/* Typing indicator */
|
|
298
337
|
#kiln-typing {
|
|
299
338
|
display: flex;
|
|
@@ -354,6 +393,19 @@
|
|
|
354
393
|
overflow-y: auto;
|
|
355
394
|
}
|
|
356
395
|
|
|
396
|
+
#kiln-input::-webkit-scrollbar {
|
|
397
|
+
width: 4px;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
#kiln-input::-webkit-scrollbar-track {
|
|
401
|
+
background: transparent;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
#kiln-input::-webkit-scrollbar-thumb {
|
|
405
|
+
background: var(--kiln-border);
|
|
406
|
+
border-radius: 2px;
|
|
407
|
+
}
|
|
408
|
+
|
|
357
409
|
#kiln-input::placeholder {
|
|
358
410
|
color: var(--kiln-text-secondary);
|
|
359
411
|
}
|
|
@@ -394,5 +446,5 @@
|
|
|
394
446
|
width: 18px;
|
|
395
447
|
height: 18px;
|
|
396
448
|
}
|
|
397
|
-
`}var T='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',z='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',I='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>';function Y(
|
|
398
|
-
`)
|
|
449
|
+
`}var T='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>',z='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>',I='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><line x1="22" y1="2" x2="11" y2="13"/><polygon points="22 2 15 22 11 13 2 9 22 2"/></svg>';function Y(n){let i=document.createDocumentFragment(),t=/(\*\*[^*]+\*\*|`[^`]+`|\n)/g,e=0,s;while((s=t.exec(n))!==null){if(s.index>e)i.appendChild(document.createTextNode(n.slice(e,s.index)));let o=s[0];if(o===`
|
|
450
|
+
`)i.appendChild(document.createElement("br"));else if(o.startsWith("**")){let r=document.createElement("strong");r.textContent=o.slice(2,-2),i.appendChild(r)}else if(o.startsWith("`")){let r=document.createElement("code");r.textContent=o.slice(1,-1),i.appendChild(r)}e=s.index+o.length}if(e<n.length)i.appendChild(document.createTextNode(n.slice(e)));return i}class k{config;client;container;shadow;messages=[];isOpen=!1;isLoading=!1;idCounter=0;greetingShown=!1;panelEl;messagesEl;typingEl;inputEl;sendEl;statusDotEl;launcherEl;constructor(n){this.config=n,this.client=new h(n.gatewayUrl,n.appName,n.widgetId),this.container=document.createElement("div"),this.container.id="kiln-widget-root",this.shadow=this.container.attachShadow({mode:"closed"}),document.body.appendChild(this.container);let i=document.createElement("style");if(i.textContent=f(this.resolveTheme()),this.shadow.appendChild(i),this.render(),this.client.onMessage((t)=>this.handleFrame(t)),this.client.onStatusChange((t)=>this.updateStatus(t)),this.client.connect(),n.greeting)this.addMessage({id:String(++this.idCounter),role:"assistant",content:n.greeting,timestamp:Date.now()}),this.greetingShown=!0}resolveTheme(){let n=this.config.theme??"auto";if(n==="auto")return window.matchMedia("(prefers-color-scheme: dark)").matches?"dark":"light";return n}render(){let n=this.config.position??"bottom-right",i=document.createElement("button");i.id="kiln-launcher",i.className=`position-${n}`,i.setAttribute("aria-label","Open chat"),i.innerHTML=T,i.addEventListener("click",()=>this.toggle()),this.launcherEl=i;let t=document.createElement("div");t.id="kiln-panel",t.className=`position-${n} hidden`,t.setAttribute("role","dialog"),t.setAttribute("aria-label","Chat");let e=document.createElement("div");e.id="kiln-header";let s=document.createElement("span");s.id="kiln-status-dot",s.className="disconnected",this.statusDotEl=s;let o=document.createElement("span");o.id="kiln-title",o.textContent=this.config.appName;let r=document.createElement("button");r.id="kiln-close",r.setAttribute("aria-label","Close chat"),r.innerHTML=z,r.addEventListener("click",()=>this.close()),e.appendChild(s),e.appendChild(o),e.appendChild(r);let p=document.createElement("div");p.id="kiln-messages",this.messagesEl=p;let c=document.createElement("div");c.id="kiln-typing",c.className="hidden";for(let d=0;d<3;d++){let x=document.createElement("span");x.className="kiln-typing-dot",c.appendChild(x)}this.typingEl=c,p.appendChild(c);let u=document.createElement("div");u.id="kiln-input-area";let a=document.createElement("textarea");a.id="kiln-input",a.rows=1,a.placeholder=this.config.placeholder??"Type a message...",a.setAttribute("aria-label","Message input"),a.addEventListener("keydown",(d)=>{if(d.key==="Enter"&&!d.shiftKey)d.preventDefault(),this.sendMessage()}),a.addEventListener("input",()=>this.autoResizeTextarea()),this.inputEl=a;let l=document.createElement("button");l.id="kiln-send",l.setAttribute("aria-label","Send message"),l.innerHTML=I,l.addEventListener("click",()=>this.sendMessage()),this.sendEl=l,u.appendChild(a),u.appendChild(l),t.appendChild(e),t.appendChild(p),t.appendChild(u),this.panelEl=t,this.shadow.appendChild(i),this.shadow.appendChild(t)}autoResizeTextarea(){this.inputEl.style.height="auto",this.inputEl.style.height=`${Math.min(this.inputEl.scrollHeight,120)}px`}open(){this.isOpen=!0,this.panelEl.classList.remove("hidden"),this.launcherEl.setAttribute("aria-expanded","true"),this.inputEl.focus(),this.scrollToBottom()}close(){this.isOpen=!1,this.panelEl.classList.add("hidden"),this.launcherEl.setAttribute("aria-expanded","false")}toggle(){if(this.isOpen)this.close();else this.open()}sendMessage(n){let i=n??this.inputEl.value.trim();if(!i||this.isLoading)return;this.removeSuggestions(),this.addMessage({id:String(++this.idCounter),role:"user",content:i,timestamp:Date.now()}),this.inputEl.value="",this.inputEl.style.height="auto",this.setLoading(!0),this.client.send(i)}addMessage(n){this.messages.push(n),this.renderMessage(n),this.scrollToBottom()}renderMessage(n){let i=document.createElement("div");i.className=`kiln-msg ${n.role}`,i.dataset.msgId=n.id;let t=document.createElement("div");if(t.className="kiln-bubble",n.role==="assistant")t.appendChild(Y(n.content));else t.textContent=n.content;i.appendChild(t),this.messagesEl.insertBefore(i,this.typingEl)}renderErrorMessage(n){let i=document.createElement("div");i.className="kiln-msg error";let t=document.createElement("div");t.className="kiln-bubble",t.textContent=n,i.appendChild(t),this.messagesEl.insertBefore(i,this.typingEl),this.scrollToBottom()}setLoading(n){if(this.isLoading=n,this.sendEl.disabled=n,this.inputEl.disabled=n,n)this.typingEl.classList.remove("hidden"),this.scrollToBottom();else this.typingEl.classList.add("hidden")}scrollToBottom(){requestAnimationFrame(()=>{this.messagesEl.scrollTop=this.messagesEl.scrollHeight})}handleFrame(n){if(n.type==="done")this.setLoading(!1),this.addMessage({id:String(++this.idCounter),role:"assistant",content:n.content,timestamp:Date.now()});else if(n.type==="error")if(this.setLoading(!1),n.code==="BUDGET_EXHAUSTED")this.renderInfoMessage(n.message);else this.renderErrorMessage(n.message);else if(n.type==="welcome"){if(n.greeting&&!this.greetingShown)this.addMessage({id:String(++this.idCounter),role:"assistant",content:n.greeting,timestamp:Date.now()}),this.greetingShown=!0;if(n.suggestions&&n.suggestions.length>0)this.renderSuggestions([...n.suggestions])}else if(n.type==="suggestions")this.renderSuggestions([...n.items])}renderSuggestions(n){this.removeSuggestions();let i=document.createElement("div");i.className="kiln-suggestions";for(let t of n){let e=document.createElement("button");e.className="kiln-chip",e.textContent=t,e.addEventListener("click",()=>{this.sendMessage(t)}),i.appendChild(e)}this.messagesEl.insertBefore(i,this.typingEl),this.scrollToBottom()}removeSuggestions(){let n=this.messagesEl.querySelector(".kiln-suggestions");if(n)n.remove()}renderInfoMessage(n){let i=document.createElement("div");i.className="kiln-msg info";let t=document.createElement("div");t.className="kiln-bubble",t.textContent=n,i.appendChild(t),this.messagesEl.insertBefore(i,this.typingEl),this.scrollToBottom()}updateStatus(n){this.statusDotEl.className=n}destroy(){this.client.disconnect(),this.container.remove()}}(function(){let n=document.currentScript;if(!n)return;let i=n.dataset.gateway,t=n.dataset.app,e=n.dataset.widgetId;if(!i||!t||!e)return;let s={gatewayUrl:i,appName:t,widgetId:e,position:n.dataset.position??"bottom-right",theme:n.dataset.theme??"auto",greeting:n.dataset.greeting,placeholder:n.dataset.placeholder},o=()=>new k(s);if(document.readyState==="loading")document.addEventListener("DOMContentLoaded",o);else o()})();})();
|