@runtypelabs/persona 4.11.1 → 4.12.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/dist/codegen.cjs +13 -13
- package/dist/codegen.d.cts +9 -0
- package/dist/codegen.d.ts +9 -0
- package/dist/codegen.js +13 -13
- package/dist/index.cjs +41 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.global.js +1 -1
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +42 -42
- package/dist/index.js.map +1 -1
- package/dist/install.global.js +1 -1
- package/dist/install.global.js.map +1 -1
- package/dist/theme-editor-preview.cjs +1 -1
- package/dist/theme-editor-preview.js +1 -1
- package/package.json +1 -1
- package/src/codegen.test.ts +43 -0
- package/src/install.test.ts +83 -0
- package/src/install.ts +48 -2
- package/src/utils/code-generators.ts +30 -4
|
@@ -8,7 +8,7 @@ ${e}`:"")+(t.description?`
|
|
|
8
8
|
${t.description}`:"");return window.confirm(n)},qf=t=>{if(t==null)return"";try{let e=JSON.stringify(t,null,2);return e.length>500?e.slice(0,500)+"\u2026":e}catch{return String(t)}},Vf=t=>{if(t===void 0)return"{}";try{let e=JSON.stringify(t);return e===void 0?"{}":e}catch{return"{}"}},Kf=t=>{if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}};function So(t,e){let n=t?.display;return n?typeof n=="string"?n:n.byType?.[e]??n.default??"panel":"panel"}function Js(t,e){return JSON.stringify({component:t==="inline"?"PersonaArtifactInline":"PersonaArtifactCard",props:{artifactId:e.artifactId,title:e.title,artifactType:e.artifactType,status:e.status,...e.file?{file:e.file}:{},...t==="inline"&&e.component?{component:e.component}:{},...t==="inline"&&e.componentProps?{componentProps:e.componentProps}:{},...e.markdown!==void 0?{markdown:e.markdown}:{}}})}var Gf="agent_",Qf="flow_";function dd(t){return t.startsWith(Gf)?{kind:"agentId",agentId:t}:t.startsWith(Qf)?{kind:"flowId",flowId:t}:null}function pd(t,e){let n=t.trim();if(!n)throw new Error("[Persona] `target` is empty.");let o=n.indexOf(":");if(o>0){let a=n.slice(0,o),l=n.slice(o+1);if(a==="runtype"){let d=dd(l);if(d)return d;throw new Error(`[Persona] target "runtype:${l}" is not a valid Runtype agent_/flow_ id.`)}let p=e?.[a];if(!p)throw new Error(`[Persona] No target provider registered for "${a}". Add a \`targetProviders.${a}\` resolver, or use a Runtype agent_/flow_ id.`);return{kind:"payload",payload:p(l).payload}}let r=dd(n);if(r)return r;let s=e?.default;if(s)return{kind:"payload",payload:s(n).payload};throw new Error(`[Persona] target "${n}" has no provider prefix and is not a Runtype agent_/flow_ id. Use "<provider>:${n}", a Runtype TypeID, or register a \`targetProviders.default\` resolver.`)}import{parse as Xf,ARR as Jf,OBJ as Yf,STR as Zf}from"partial-json";var Pi="ask_user_question",Or=8,Go="data-persona-ask-sheet-for",eg="Other",tg="Other\u2026",fd="Type your own answer here",gd="Send",ng="Next",og="Back",rg="Submit all",sg="Skip",ag=3,Ii="data-ask-current-index",Ri="data-ask-question-count",md="data-ask-answers",Wi="data-ask-grouped",hd="data-ask-layout",ig=t=>t.layout==="pills"?"pills":"rows",lg=t=>t.getAttribute(hd)==="pills"?"pills":"rows",ud=!1,yd=t=>t.replace(/["\\]/g,"\\$&"),To=t=>t.variant==="tool"&&!!t.toolCall&&t.toolCall.name===Pi,Hi=t=>t?.features?.askUserQuestion??{},Qo=t=>{let e=t.toolCall;if(!e)return{payload:null,complete:!1};let n=e.status==="complete";if(e.args&&typeof e.args=="object")return{payload:e.args,complete:n};let o=e.chunks;if(!o||o.length===0)return{payload:null,complete:n};try{let r=o.join(""),s=Xf(r,Zf|Yf|Jf);if(s&&typeof s=="object")return{payload:s,complete:n}}catch{}return{payload:null,complete:n}},_r=t=>{let e=Array.isArray(t?.questions)?t.questions:[];return e.length>Or&&!ud&&(ud=!0,typeof console<"u"&&console.warn(`[AgentWidget] ask_user_question received ${e.length} questions; truncating to ${Or}.`)),e.slice(0,Or)},cg=t=>_r(t)[0]??null,dg=(t,e)=>_r(t)[e]??null,pg=(t,e)=>{let n=e.styles;n&&(n.sheetBackground&&t.style.setProperty("--persona-ask-sheet-bg",n.sheetBackground),n.sheetBorder&&t.style.setProperty("--persona-ask-sheet-border",n.sheetBorder),n.sheetShadow&&t.style.setProperty("--persona-ask-sheet-shadow",n.sheetShadow),n.pillBackground&&t.style.setProperty("--persona-ask-pill-bg",n.pillBackground),n.pillBackgroundSelected&&t.style.setProperty("--persona-ask-pill-bg-selected",n.pillBackgroundSelected),n.pillTextColor&&t.style.setProperty("--persona-ask-pill-fg",n.pillTextColor),n.pillTextColorSelected&&t.style.setProperty("--persona-ask-pill-fg-selected",n.pillTextColorSelected),n.pillBorderRadius&&t.style.setProperty("--persona-ask-pill-radius",n.pillBorderRadius),n.customInputBackground&&t.style.setProperty("--persona-ask-input-bg",n.customInputBackground))},bd=(t,e,n)=>{if(t!=="rows")return null;let o=h("span","persona-ask-row-affordance");if(o.setAttribute("aria-hidden","true"),e){let r=h("span","persona-ask-row-check");o.appendChild(r)}else{let r=h("span","persona-ask-row-badge");r.textContent=String(n+1),o.appendChild(r)}return o},ug=(t,e,n,o)=>{let s=h("button",n==="rows"?"persona-ask-pill persona-ask-row persona-pointer-events-auto":"persona-ask-pill persona-pointer-events-auto");if(s.type="button",s.setAttribute("role",o?"checkbox":"button"),s.setAttribute("aria-pressed","false"),s.setAttribute("data-ask-user-action","pick"),s.setAttribute("data-option-index",String(e)),s.setAttribute("data-option-label",t.label),n==="rows"){let a=h("span","persona-ask-row-content"),l=h("span","persona-ask-row-label");if(l.textContent=t.label,a.appendChild(l),t.description){let d=h("span","persona-ask-row-description");d.textContent=t.description,a.appendChild(d)}s.appendChild(a);let p=bd(n,o,e);p&&s.appendChild(p)}else s.textContent=t.label,t.description&&(s.title=t.description);return s},fg=t=>{let n=h("span",t==="rows"?"persona-ask-pill persona-ask-row persona-ask-pill-skeleton persona-pointer-events-none":"persona-ask-pill persona-ask-pill-skeleton persona-pointer-events-none");return n.setAttribute("aria-hidden","true"),n},gg=(t,e,n,o)=>{let s=h("div",o==="rows"?"persona-ask-pills persona-ask-pills--rows persona-flex persona-flex-col persona-gap-2":"persona-ask-pills persona-flex persona-flex-wrap persona-gap-2");s.setAttribute("role","group"),s.setAttribute("data-ask-pill-list","true");let a=!!t?.multiSelect,p=(Array.isArray(t?.options)?t.options:[]).filter(c=>c&&typeof c.label=="string"&&c.label.length>0);if(p.length===0&&!n){for(let c=0;c<ag;c++)s.appendChild(fg(o));return s}if(p.forEach((c,u)=>{s.appendChild(ug(c,u,o,a))}),t?.allowFreeText!==!1){let c=o==="rows"?eg:tg;if(o==="rows"){let u=h("div","persona-ask-pill persona-ask-row persona-ask-row--other persona-ask-pill-custom persona-pointer-events-auto");u.setAttribute("data-ask-user-action","focus-free-text"),u.setAttribute("data-option-index",String(p.length)),u.setAttribute("data-ask-other-row","true");let w=h("span","persona-ask-row-content"),f=document.createElement("input");f.type="text",f.className="persona-ask-row-input persona-flex-1 persona-pointer-events-auto",f.placeholder=e.freeTextPlaceholder??fd,f.setAttribute("data-ask-free-text-input","true"),f.setAttribute("aria-label",e.freeTextLabel??c),w.appendChild(f),u.appendChild(w);let v=bd(o,a,p.length);v&&u.appendChild(v),s.appendChild(u)}else{let u=h("button","persona-ask-pill persona-ask-pill-custom persona-pointer-events-auto");u.type="button",u.setAttribute("data-ask-user-action","open-free-text"),u.textContent=e.freeTextLabel??c,s.appendChild(u)}}return s},vd=(t,e)=>{let o=h("div",e==="rows"?"persona-ask-free-text persona-ask-free-text--rows persona-flex persona-gap-2 persona-mt-2":"persona-ask-free-text persona-hidden persona-flex persona-gap-2 persona-mt-2");o.setAttribute("data-ask-free-text-row","true");let r=document.createElement("input");if(r.type="text",r.className="persona-ask-free-text-input persona-flex-1 persona-pointer-events-auto",r.placeholder=t.freeTextPlaceholder??fd,r.setAttribute("data-ask-free-text-input","true"),o.appendChild(r),e!=="rows"){let s=h("button","persona-ask-free-text-submit persona-pointer-events-auto");s.type="button",s.textContent=t.submitLabel??gd,s.setAttribute("data-ask-user-action","submit-free-text"),o.appendChild(s)}return o},mg=t=>{let e=h("div","persona-ask-multi-actions persona-flex persona-justify-end persona-mt-2");e.setAttribute("data-ask-multi-actions","true");let n=h("button","persona-ask-multi-submit persona-pointer-events-auto");return n.type="button",n.textContent=t.submitLabel??gd,n.setAttribute("data-ask-user-action","submit-multi"),n.disabled=!0,e.appendChild(n),e},hg=(t,e,n)=>{let o=h("div","persona-ask-nav persona-flex persona-justify-between persona-items-center persona-gap-2 persona-mt-2");o.setAttribute("data-ask-nav-row","true");let r=h("button","persona-ask-nav-back persona-pointer-events-auto");r.type="button",r.textContent=n.backLabel??og,r.setAttribute("data-ask-user-action","back"),r.disabled=t===0,o.appendChild(r);let s=h("div","persona-ask-nav-right persona-flex persona-items-center persona-gap-2"),a=h("button","persona-ask-nav-skip persona-pointer-events-auto");a.type="button",a.textContent=n.skipLabel??sg,a.setAttribute("data-ask-user-action","skip"),s.appendChild(a);let l=h("button","persona-ask-nav-next persona-pointer-events-auto");l.type="button";let p=t===e-1;return l.textContent=p?n.submitAllLabel??rg:n.nextLabel??ng,l.setAttribute("data-ask-user-action",p?"submit-all":"next"),l.disabled=!0,s.appendChild(l),o.appendChild(s),o},Mo=t=>{let e=t.getAttribute(md);if(!e)return{};try{let n=JSON.parse(e);return n&&typeof n=="object"?n:{}}catch{return{}}},wd=(t,e)=>{t.setAttribute(md,JSON.stringify(e))},dn=t=>{let e=Number(t.getAttribute(Ii)??"0");return Number.isFinite(e)?Math.max(0,Math.floor(e)):0},yg=(t,e)=>{t.setAttribute(Ii,String(Math.max(0,Math.floor(e))))},Xo=t=>{let e=Number(t.getAttribute(Ri)??"1");return Number.isFinite(e)?Math.max(1,Math.floor(e)):1},eo=t=>t.getAttribute(Wi)==="true",bg=(t,e)=>{let n=t.agentMetadata?.askUserQuestionAnswers;if(!n||typeof n!="object")return{};let o={};return e.forEach((r,s)=>{let a=typeof r?.question=="string"?r.question:"";if(a&&Object.prototype.hasOwnProperty.call(n,a)){let l=n[a];(typeof l=="string"||Array.isArray(l))&&(o[s]=l)}}),o},vg=(t,e)=>{let n=t.agentMetadata?.askUserQuestionIndex;return typeof n!="number"||!Number.isFinite(n)?0:Math.max(0,Math.min(e-1,Math.floor(n)))},Ys=(t,e)=>{let{payload:n}=Qo(e),o=_r(n),r=Mo(t),s={},a=new Set;return o.forEach((l,p)=>{let d=typeof l?.question=="string"?l.question:"";d&&(a.has(d)&&typeof console<"u"&&console.warn(`[AgentWidget] ask_user_question has duplicate question text "${d}"; later answer wins.`),a.add(d),Object.prototype.hasOwnProperty.call(r,p)&&(s[d]=r[p]))}),s},xd=t=>{let e=Mo(t),n=dn(t),o=e[n],r=new Set;typeof o=="string"?r.add(o):Array.isArray(o)&&o.forEach(p=>r.add(p));let s=t.querySelectorAll('[data-ask-user-action="pick"][data-option-label]');s.forEach(p=>{let d=p.getAttribute("data-option-label")??"",c=r.has(d);p.setAttribute("aria-pressed",c?"true":"false"),p.classList.toggle("persona-ask-pill-selected",c)});let a=new Set(Array.from(s).map(p=>p.getAttribute("data-option-label")??"")),l=t.querySelector('[data-ask-free-text-input="true"]');l&&(typeof o=="string"&&o.length>0&&!a.has(o)?(l.value=o,l.closest('[data-ask-free-text-row="true"]')?.classList.remove("persona-hidden")):l.value="")},Cd=t=>{if(!eo(t))return;let e=Mo(t),n=dn(t),o=e[n],r=typeof o=="string"&&o.length>0||Array.isArray(o)&&o.length>0,s=t.querySelector('[data-ask-user-action="next"], [data-ask-user-action="submit-all"]');s&&(s.disabled=!r);let a=t.querySelector('[data-ask-user-action="submit-multi"]');if(a){let l=Array.from(t.querySelectorAll('[aria-pressed="true"][data-option-label]'));a.disabled=l.length===0}},Bi=(t,e,n)=>{let o=Hi(n),r=lg(t),{payload:s,complete:a}=Qo(e),l=eo(t),p=dn(t),d=Xo(t),c=l?dg(s,p):cg(s),u=!!c?.multiSelect,w=t.querySelector('[data-ask-step-inline="true"]');w&&(w.textContent=l?`${p+1}/${d}`:"");let f=t.querySelector('[data-ask-stepper="true"]');f&&f.remove();let v=t.querySelector('[data-ask-question="true"]');if(v){let k=typeof c?.question=="string"?c.question:"";v.textContent=k,v.classList.toggle("persona-ask-question-skeleton",!k&&!a)}let C=t.querySelector('[data-ask-pill-list="true"]');if(C){let k=gg(c,o,a,r);C.replaceWith(k)}if(r!=="rows"){let k=t.querySelector('[data-ask-free-text-row="true"]');k&&k.replaceWith(vd(o,r))}let I=t.querySelector('[data-ask-multi-actions="true"]');!l&&u&&!I?t.appendChild(mg(o)):(!u||l)&&I&&I.remove(),t.setAttribute("data-multi-select",u?"true":"false");let B=t.querySelector('[data-ask-nav-row="true"]');if(l){let k=hg(p,d,o);B?B.replaceWith(k):t.appendChild(k)}else B&&B.remove();xd(t),Cd(t)},wg=(t,e,n)=>{let o=Hi(e),r=ig(o),s=t.toolCall.id,a=_r(n),l=Math.max(1,a.length),p=l>1,d=bg(t,a),c=p?vg(t,l):0,u=h("div",["persona-ask-sheet",`persona-ask-sheet--${r}`,"persona-pointer-events-auto","persona-ask-sheet-enter"].join(" "));u.setAttribute(Go,s),u.setAttribute("data-tool-call-id",s),u.setAttribute("data-message-id",t.id),u.setAttribute(Ri,String(l)),u.setAttribute(Ii,String(c)),u.setAttribute(Wi,p?"true":"false"),u.setAttribute(hd,r),wd(u,d),u.setAttribute("role","group"),u.setAttribute("aria-label","Suggested answers"),o.slideInMs!==void 0&&u.style.setProperty("--persona-ask-sheet-duration",`${o.slideInMs}ms`),pg(u,o);let w=h("div","persona-ask-sheet-header persona-flex persona-items-center persona-gap-3"),f=h("div","persona-ask-sheet-question persona-flex-1");f.setAttribute("data-ask-question","true"),f.textContent="",w.appendChild(f);let v=h("span","persona-ask-sheet-step-inline");v.setAttribute("data-ask-step-inline","true"),v.textContent="",w.appendChild(v),u.appendChild(w);let I=h("div",r==="rows"?"persona-ask-pills persona-ask-pills--rows persona-flex persona-flex-col persona-gap-2":"persona-ask-pills persona-flex persona-flex-wrap persona-gap-2");return I.setAttribute("data-ask-pill-list","true"),I.setAttribute("role","group"),u.appendChild(I),r!=="rows"&&u.appendChild(vd(o,r)),Bi(u,t,e),requestAnimationFrame(()=>{requestAnimationFrame(()=>u.classList.remove("persona-ask-sheet-enter"))}),u},xg=(t,e,n)=>{let{payload:o}=Qo(e),r=Math.max(1,_r(o).length);r>Xo(t)&&(t.setAttribute(Ri,String(r)),r>1&&!eo(t)&&t.setAttribute(Wi,"true")),Bi(t,e,n)};var Zs=(t,e,n)=>{if(!n||!To(t)||Hi(e).enabled===!1)return;let r=t.toolCall.id;n.querySelectorAll(`[${Go}]`).forEach(d=>{d.getAttribute(Go)!==r&&d.remove()});let a=n.querySelector(`[${Go}="${yd(r)}"]`);if(a){xg(a,t,e);return}let{payload:l}=Qo(t),p=wg(t,e,l);n.appendChild(p)},Jo=(t,e)=>{if(!t)return;let n=e?`[${Go}="${yd(e)}"]`:`[${Go}]`;t.querySelectorAll(n).forEach(r=>{r.classList.add("persona-ask-sheet-leave");let s=Number.parseInt(getComputedStyle(r).getPropertyValue("--persona-ask-sheet-duration")||"180",10);setTimeout(()=>r.remove(),Number.isFinite(s)?s:180)})},Di=t=>Array.from(t.querySelectorAll('[aria-pressed="true"][data-option-label]')).map(e=>e.getAttribute("data-option-label")).filter(e=>typeof e=="string"&&e.length>0),to=(t,e)=>{let n=Mo(t),o=dn(t);typeof e=="string"&&e.length===0||Array.isArray(e)&&e.length===0?delete n[o]:n[o]=e,wd(t,n),xd(t),Cd(t)},ea=(t,e,n,o)=>{let r=Xo(t),s=Math.max(0,Math.min(r-1,o));yg(t,s),Bi(t,e,n)};var Dn="suggest_replies";var Cg={type:"object",properties:{suggestions:{type:"array",minItems:1,maxItems:4,description:"1-4 short, distinct follow-up replies, phrased in the user's voice.",items:{type:"string",minLength:1,maxLength:60}}},required:["suggestions"],additionalProperties:!1},Ad={name:Dn,description:`Offer the user tappable quick-reply suggestions for their next message. Call at most once per turn, as the LAST action after your reply text is complete. Each suggestion is sent verbatim as the user's next message, so phrase suggestions in the user's voice (e.g. "Tell me more about pricing"). Keep them short and distinct. The result only confirms the suggestions were shown: do not add further commentary after calling this tool; end your turn.`,parametersSchema:Cg,origin:"sdk",annotations:{readOnlyHint:!0}},Fi=()=>({content:[{type:"text",text:"Suggestions shown to the user."}]}),Ni=t=>t.variant==="tool"&&t.toolCall?.name===Dn,Ag=t=>{let e=t;if(typeof e=="string")try{e=JSON.parse(e)}catch{return[]}let n=e?.suggestions;if(!Array.isArray(n))return[];let o=n.filter(r=>typeof r=="string").map(r=>r.trim()).filter(r=>r.length>0);return o.length>4?(console.warn(`[persona] suggest_replies: ${o.length} suggestions exceeds the cap of 4; extra suggestions dropped.`),o.slice(0,4)):o},Sd=t=>{for(let e=t.length-1;e>=0;e--){let n=t[e];if(n.role==="user")return null;if(!Ni(n))continue;let o=Ag(n.toolCall?.args);return o.length>0?o:null}return null},Td=t=>{let e=t?.features?.suggestReplies;return e?.expose===!0&&e.enabled!==!1};var Sg={type:"object",properties:{questions:{type:"array",minItems:1,maxItems:Or,description:"Questions to ask the user. Prefer a single question.",items:{type:"object",properties:{question:{type:"string",description:"The complete question, ending with a question mark."},header:{type:"string",maxLength:12,description:'Short topic label, e.g. "Auth method".'},options:{type:"array",minItems:2,maxItems:4,description:'2-4 distinct choices. Do NOT add an "Other" option: free text is automatic.',items:{type:"object",properties:{label:{type:"string",description:"Concise choice text (1-5 words)."},description:{type:"string",description:"What the option means or implies."}},required:["label"],additionalProperties:!1}},multiSelect:{type:"boolean",description:"Allow selecting multiple options. Default false."},allowFreeText:{type:"boolean",description:"Show a free-text input. Default true."}},required:["question","options"],additionalProperties:!1}}},required:["questions"],additionalProperties:!1},Tg={name:Pi,description:"Ask the user multiple-choice questions and wait for their answers. Use only when blocked on a decision that is the user's to make: a preference, a choice between valid approaches, or information you cannot infer. Each question offers 2-4 options plus an automatic free-text input. The result maps each question to its answer (an array when multiSelect); a question absent from the result was skipped.",parametersSchema:Sg,origin:"sdk",annotations:{readOnlyHint:!0}},ta=t=>{let e=[],n=t?.features?.askUserQuestion;return n?.expose===!0&&n.enabled!==!1&&e.push(Tg),Td(t)&&e.push(Ad),e};import{parse as Mg,STR as Eg,OBJ as kg}from"partial-json";var Md=t=>t.replace(/\\n/g,`
|
|
9
9
|
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\"),no=t=>{if(t===null)return"null";if(t===void 0)return"";if(typeof t=="string")return t;if(typeof t=="number"||typeof t=="boolean")return String(t);try{return JSON.stringify(t,null,2)}catch{return String(t)}},Lg=t=>{let e=t.completedAt??Date.now(),n=t.startedAt??e,r=(t.durationMs!==void 0?t.durationMs:Math.max(0,e-n))/1e3;return r<.1?"Thought for <0.1 seconds":`Thought for ${r>=10?Math.round(r).toString():r.toFixed(1).replace(/\.0$/,"")} seconds`},Ed=t=>t.status==="complete"?Lg(t):t.status==="pending"?"Waiting":"",Pg=t=>{let n=(typeof t.duration=="number"?t.duration:typeof t.durationMs=="number"?t.durationMs:Math.max(0,(t.completedAt??Date.now())-(t.startedAt??t.completedAt??Date.now())))/1e3;return n<.1?"Used tool for <0.1 seconds":`Used tool for ${n>=10?Math.round(n).toString():n.toFixed(1).replace(/\.0$/,"")} seconds`};var kd=t=>t.status==="complete"?Pg(t):"Using tool...",na=t=>{let e=t/1e3;return e<.1?"<0.1s":e>=10?`${Math.round(e)}s`:`${e.toFixed(1).replace(/\.0$/,"")}s`},zr=t=>{let e=typeof t.duration=="number"?t.duration:typeof t.durationMs=="number"?t.durationMs:Math.max(0,(t.completedAt??Date.now())-(t.startedAt??t.completedAt??Date.now()));return na(e)},oa=t=>{let e=t.durationMs!==void 0?t.durationMs:Math.max(0,(t.completedAt??Date.now())-(t.startedAt??t.completedAt??Date.now()));return na(e)},Oi=(t,e,n)=>{if(!e)return n;let o=t.name?.trim()||"tool",r=zr(t);return e.replace(/\{toolName\}/g,o).replace(/\{duration\}/g,r)},ra=(t,e)=>{let n=t.replace(/\{toolName\}/g,e),o=[],r=/\*\*(.+?)\*\*|\*(.+?)\*|~(.+?)~/g,s=0,a;for(;(a=r.exec(n))!==null;)a.index>s&&$r(o,n.slice(s,a.index),[]),a[1]!==void 0?$r(o,a[1],["bold"]):a[2]!==void 0?$r(o,a[2],["italic"]):a[3]!==void 0&&$r(o,a[3],["dim"]),s=a.index+a[0].length;return s<n.length&&$r(o,n.slice(s),[]),o},$r=(t,e,n)=>{let o=e.split("{duration}");for(let r=0;r<o.length;r++)o[r]&&t.push({text:o[r],styles:n}),r<o.length-1&&t.push({text:"{duration}",styles:n,isDuration:!0})},Ig=()=>{let t=null,e=0,n=o=>{let r=/"text"\s*:\s*"((?:[^"\\]|\\.|")*?)"/,s=o.match(r);if(s&&s[1])try{return s[1].replace(/\\n/g,`
|
|
10
10
|
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")}catch{return s[1]}let a=/"text"\s*:\s*"((?:[^"\\]|\\.)*)/,l=o.match(a);if(l&&l[1])try{return l[1].replace(/\\n/g,`
|
|
11
|
-
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")}catch{return l[1]}return null};return{getExtractedText:()=>t,processChunk:async o=>{if(o.length<=e)return t!==null?{text:t,raw:o}:null;let r=o.trim();if(!r.startsWith("{")&&!r.startsWith("["))return null;let s=n(o);return s!==null&&(t=s),e=o.length,t!==null?{text:t,raw:o}:null},close:async()=>{}}},Ur=t=>{try{let e=JSON.parse(t);if(e&&typeof e=="object"&&typeof e.text=="string")return e.text}catch{return null}return null},Ld=()=>{let t={processChunk:e=>null,getExtractedText:()=>null};return t.__isPlainTextParser=!0,t},Pd=()=>{let t=Ig();return{processChunk:async e=>{let n=e.trim();return!n.startsWith("{")&&!n.startsWith("[")?null:t.processChunk(e)},getExtractedText:t.getExtractedText.bind(t),close:t.close?.bind(t)}},Id=()=>{let t=null,e=0;return{getExtractedText:()=>t,processChunk:n=>{let o=n.trim();if(!o.startsWith("{")&&!o.startsWith("["))return null;if(n.length<=e)return t!==null||t===""?{text:t||"",raw:n}:null;try{let r=Mg(n,Eg|kg);r&&typeof r=="object"&&(r.component&&typeof r.component=="string"?t=typeof r.text=="string"?Md(r.text):"":r.type==="init"&&r.form?t="":typeof r.text=="string"&&(t=Md(r.text)))}catch{}return e=n.length,t!==null?{text:t,raw:n}:null},close:()=>{}}};var Rd=()=>{let t=null;return{processChunk:e=>{if(!e.trim().startsWith("<"))return null;let o=e.match(/<text[^>]*>([\s\S]*?)<\/text>/);return o&&o[1]?(t=o[1],{text:t,raw:e}):null},getExtractedText:()=>t}};var Wd="4.11.1";var jr=Wd;var Wg="https://api.runtype.com/v1/dispatch",sa="https://api.runtype.com";function Hg(t){let e=t.toLowerCase(),o={"application/pdf":"pdf","application/json":"json","application/zip":"zip","text/plain":"txt","text/csv":"csv","text/markdown":"md"}[e];if(o)return`attachment.${o}`;let r=e.indexOf("/");if(r>0){let s=e.slice(r+1).split(";")[0]?.trim()??"";if(s&&s!=="octet-stream"&&/^[a-z0-9.+-]+$/i.test(s))return`attachment.${s}`}return"attachment"}var _i=t=>!!(t.contentParts&&t.contentParts.length>0||t.llmContent&&t.llmContent.trim().length>0||t.rawContent&&t.rawContent.trim().length>0||t.content&&t.content.trim().length>0);function Bg(t){switch(t){case"json":return Id;case"regex-json":return Pd;case"xml":return Rd;default:return Ld}}var Hd=t=>t.startsWith("{")||t.startsWith("[")||t.startsWith("<");function Dg(t,e){if(!t)return e;let n=t.trim(),o=e.trim();if(n.length===0)return e;if(o.length===0)return t;let r=Hd(n);if(!Hd(o))return t;if(!r||o===n||o.startsWith(n))return e;let a=Ur(t);return Ur(e)!==null&&a===null?e:t}var qr=class{constructor(e={}){this.config=e;this.clientSession=null;this.sessionInitPromise=null;this.lastSentClientToolsFingerprint=null;this.clientToolsFingerprintSessionId=null;this.sentNonEmptyClientToolsSessionId=null;if(e.target&&(e.agentId||e.flowId||e.agent))throw new Error("[Persona] `target` is mutually exclusive with `agentId`, `flowId`, and `agent`. Set only one routing field.");this.apiUrl=e.apiUrl??Wg,this.headers={"Content-Type":"application/json","X-Persona-Version":jr,...e.headers},this.debug=!!e.debug,this.createStreamParser=e.streamParser??Bg(e.parserType),this.contextProviders=e.contextProviders??[],this.requestMiddleware=e.requestMiddleware,this.customFetch=e.customFetch,this.parseSSEEvent=e.parseSSEEvent,this.getHeaders=e.getHeaders,this.webMcpBridge=e.webmcp?.enabled===!0?new Xs(e.webmcp):null}updateConfig(e){this.config=e}setSSEEventCallback(e){this.onSSEEvent=e}setWebMcpConfirmHandler(e){this.webMcpBridge?.setConfirmHandler(e)}isWebMcpOperational(){return this.webMcpBridge?.isOperational()===!0}executeWebMcpToolCall(e,n,o){return this.webMcpBridge?this.webMcpBridge.executeToolCall(e,n,o):null}getSSEEventCallback(){return this.onSSEEvent}isClientTokenMode(){return!!this.config.clientToken}routing(){let{agentId:e,flowId:n,target:o,targetProviders:r}=this.config;if(!o)return{agentId:e,flowId:n};let s=pd(o,r);return s.kind==="agentId"?{agentId:s.agentId}:s.kind==="flowId"?{flowId:s.flowId}:{targetPayload:s.payload}}isAgentMode(){return!!(this.config.agent||this.routing().agentId)}getClientApiUrl(e){return`${this.config.apiUrl?.replace(/\/+$/,"").replace(/\/v1\/dispatch$/,"")||sa}/v1/client/${e}`}getClientSession(){return this.clientSession}async initSession(){if(!this.isClientTokenMode())throw new Error("initSession() only available in client token mode");if(this.clientSession&&new Date<this.clientSession.expiresAt)return this.clientSession;if(this.sessionInitPromise)return this.sessionInitPromise;this.sessionInitPromise=this._doInitSession();try{let e=await this.sessionInitPromise;return this.clientSession=e,this.resetClientToolsFingerprint(),this.config.onSessionInit?.(e),e}finally{this.sessionInitPromise=null}}async _doInitSession(){let e=this.config.getStoredSessionId?.()||null,n=this.routing(),o=n.agentId??n.flowId,r={token:this.config.clientToken,...o&&{flowId:o},...e&&{sessionId:e}},s=await fetch(this.getClientApiUrl("init"),{method:"POST",headers:{"Content-Type":"application/json","X-Persona-Version":jr},body:JSON.stringify(r)});if(!s.ok){let l=await s.json().catch(()=>({error:"Session initialization failed"}));throw s.status===401?new Error(`Invalid client token: ${l.hint||l.error}`):s.status===403?new Error(`Origin not allowed: ${l.hint||l.error}`):new Error(l.error||"Failed to initialize session")}let a=await s.json();return this.config.setStoredSessionId&&this.config.setStoredSessionId(a.sessionId),{sessionId:a.sessionId,expiresAt:new Date(a.expiresAt),flow:a.flow,config:{welcomeMessage:a.config.welcomeMessage,placeholder:a.config.placeholder,theme:a.config.theme}}}clearClientSession(){this.clientSession=null,this.sessionInitPromise=null,this.resetClientToolsFingerprint()}resetClientToolsFingerprint(){this.lastSentClientToolsFingerprint=null,this.clientToolsFingerprintSessionId=null,this.sentNonEmptyClientToolsSessionId=null}getFeedbackApiUrl(){return`${this.config.apiUrl?.replace(/\/+$/,"").replace(/\/v1\/dispatch$/,"")||sa}/v1/client/feedback`}async sendFeedback(e){if(!this.isClientTokenMode())throw new Error("sendFeedback() only available in client token mode");if(!this.getClientSession())throw new Error("No active session. Please initialize session first.");if(["upvote","downvote","copy"].includes(e.type)&&!e.messageId)throw new Error(`messageId is required for ${e.type} feedback type`);if(e.type==="csat"&&(e.rating===void 0||e.rating<1||e.rating>5))throw new Error("CSAT rating must be between 1 and 5");if(e.type==="nps"&&(e.rating===void 0||e.rating<0||e.rating>10))throw new Error("NPS rating must be between 0 and 10");this.debug&&console.debug("[AgentWidgetClient] sending feedback",e);let r={...e,...this.config.clientToken&&{token:this.config.clientToken}},s=await fetch(this.getFeedbackApiUrl(),{method:"POST",headers:{"Content-Type":"application/json","X-Persona-Version":jr},body:JSON.stringify(r)});if(!s.ok){let a=await s.json().catch(()=>({error:"Feedback submission failed"}));throw s.status===401?(this.clientSession=null,this.config.onSessionExpired?.(),new Error("Session expired. Please refresh to continue.")):new Error(a.error||"Failed to submit feedback")}}async submitMessageFeedback(e,n){let o=this.getClientSession();if(!o)throw new Error("No active session. Please initialize session first.");return this.sendFeedback({sessionId:o.sessionId,messageId:e,type:n})}async submitCSATFeedback(e,n){let o=this.getClientSession();if(!o)throw new Error("No active session. Please initialize session first.");return this.sendFeedback({sessionId:o.sessionId,type:"csat",rating:e,comment:n})}async submitNPSFeedback(e,n){let o=this.getClientSession();if(!o)throw new Error("No active session. Please initialize session first.");return this.sendFeedback({sessionId:o.sessionId,type:"nps",rating:e,comment:n})}async dispatch(e,n){return e.signal?.throwIfAborted(),this.isClientTokenMode()?this.dispatchClientToken(e,n):this.isAgentMode()?this.dispatchAgent(e,n):this.dispatchProxy(e,n)}async dispatchClientToken(e,n){n({type:"status",status:"connecting"});try{let o=await this.initSession();if(new Date>=new Date(o.expiresAt.getTime()-6e4)){this.clearClientSession(),this.config.onSessionExpired?.();let d=new Error("Session expired. Please refresh to continue.");throw n({type:"error",error:d}),d}let r=await this.buildPayload(e.messages),s=r.metadata?Object.fromEntries(Object.entries(r.metadata).filter(([d])=>d!=="sessionId"&&d!=="session_id")):void 0,a={sessionId:o.sessionId,messages:e.messages.filter(_i).map(d=>({id:d.id,role:d.role,content:d.contentParts??d.llmContent??d.rawContent??d.content})),...e.assistantMessageId&&{assistantMessageId:e.assistantMessageId},...s&&Object.keys(s).length>0&&{metadata:s},...r.inputs&&Object.keys(r.inputs).length>0&&{inputs:r.inputs},...r.context&&{context:r.context}},{response:l,commit:p}=await this.sendWithClientToolsDiff(o.sessionId,r.clientTools,d=>{let c={...a,...d};return this.debug&&console.debug("[AgentWidgetClient] client token dispatch",c),fetch(this.getClientApiUrl("chat"),{method:"POST",headers:{"Content-Type":"application/json","X-Persona-Version":jr},body:JSON.stringify(c),signal:e.signal})});if(!l.ok){let d=await l.json().catch(()=>({error:"Chat request failed"}));if(l.status===401){this.clearClientSession(),this.config.onSessionExpired?.();let u=new Error("Session expired. Please refresh to continue.");throw n({type:"error",error:u}),u}if(l.status===429){let u=new Error(d.hint||"Message limit reached for this session.");throw n({type:"error",error:u}),u}let c=new Error(d.error||"Failed to send message");throw n({type:"error",error:c}),c}if(!l.body){let d=new Error("No response body received");throw n({type:"error",error:d}),d}p(),n({type:"status",status:"connected"});try{await this.streamResponse(l.body,n,e.assistantMessageId)}finally{n({type:"status",status:"idle"})}}catch(o){let r=o instanceof Error?o:new Error(String(o));throw!r.message.includes("Session expired")&&!r.message.includes("Message limit")&&n({type:"error",error:r}),r}}async dispatchProxy(e,n){n({type:"status",status:"connecting"});let o=await this.buildPayload(e.messages);this.debug&&console.debug("[AgentWidgetClient] dispatch payload",o);let r={...this.headers};if(this.getHeaders)try{let a=await this.getHeaders();r={...r,...a}}catch(a){typeof console<"u"&&console.error("[AgentWidget] getHeaders error:",a)}let s;if(this.customFetch)try{s=await this.customFetch(this.apiUrl,{method:"POST",headers:r,body:JSON.stringify(o),signal:e.signal},o)}catch(a){let l=a instanceof Error?a:new Error(String(a));throw n({type:"error",error:l}),l}else s=await fetch(this.apiUrl,{method:"POST",headers:r,body:JSON.stringify(o),signal:e.signal});if(!s.ok||!s.body){let a=new Error(`Chat backend request failed: ${s.status} ${s.statusText}`);throw n({type:"error",error:a}),a}n({type:"status",status:"connected"});try{await this.streamResponse(s.body,n)}finally{n({type:"status",status:"idle"})}}async dispatchAgent(e,n){n({type:"status",status:"connecting"});let o=await this.buildAgentPayload(e.messages);this.debug&&console.debug("[AgentWidgetClient] agent dispatch payload",o);let r={...this.headers};if(this.getHeaders)try{let a=await this.getHeaders();r={...r,...a}}catch(a){typeof console<"u"&&console.error("[AgentWidget] getHeaders error:",a)}let s;if(this.customFetch)try{s=await this.customFetch(this.apiUrl,{method:"POST",headers:r,body:JSON.stringify(o),signal:e.signal},o)}catch(a){let l=a instanceof Error?a:new Error(String(a));throw n({type:"error",error:l}),l}else s=await fetch(this.apiUrl,{method:"POST",headers:r,body:JSON.stringify(o),signal:e.signal});if(!s.ok||!s.body){let a=new Error(`Agent execution request failed: ${s.status} ${s.statusText}`);throw n({type:"error",error:a}),a}n({type:"status",status:"connected"});try{await this.streamResponse(s.body,n,e.assistantMessageId)}finally{n({type:"status",status:"idle"})}}async processStream(e,n,o,r){n({type:"status",status:"connected"});try{await this.streamResponse(e,n,o,r)}finally{n({type:"status",status:"idle"})}}async resolveApproval(e,n){let r=`${this.config.apiUrl?.replace(/\/+$/,"").replace(/\/v1\/dispatch$/,"")||sa}/v1/agents/${e.agentId}/approve`,s={"Content-Type":"application/json",...this.headers};return this.getHeaders&&Object.assign(s,await this.getHeaders()),fetch(r,{method:"POST",headers:s,body:JSON.stringify({executionId:e.executionId,approvalId:e.approvalId,decision:n,streamResponse:!0})})}async sendWithClientToolsDiff(e,n,o,r){let s=!!(n&&n.length>0),a=s?ld(n):void 0,l=this.clientToolsFingerprintSessionId===e,p=s&&l&&this.lastSentClientToolsFingerprint===a,d=!s&&r?.emptyMeansReplace===!0&&this.sentNonEmptyClientToolsSessionId===e,c=!1,u;for(let w=0;;w++){if(u=await o({...s&&(c||!p)&&n?{clientTools:n}:{},...d?{clientTools:[]}:{},...a?{clientToolsFingerprint:a}:{}}),u.status===409&&w===0&&s&&(await u.clone().json().catch(()=>null))?.error==="client_tools_resend_required"){c=!0,this.lastSentClientToolsFingerprint=null;continue}break}return{response:u,commit:()=>{this.lastSentClientToolsFingerprint=a??null,this.clientToolsFingerprintSessionId=e,s?this.sentNonEmptyClientToolsSessionId=e:d&&(this.sentNonEmptyClientToolsSessionId=null)}}}async resumeFlow(e,n,o){let r=this.isClientTokenMode(),s=r?this.getClientApiUrl("resume"):`${this.config.apiUrl?.replace(/\/+$/,"")||sa}/resume`,a;r&&(a=(await this.initSession()).sessionId);let l={"Content-Type":"application/json",...this.headers};this.getHeaders&&Object.assign(l,await this.getHeaders());let p={executionId:e,toolOutputs:n,streamResponse:o?.streamResponse??!0};if(a&&(p.sessionId=a),r&&a){let d=[...ta(this.config),...await this.webMcpBridge?.snapshotForDispatch()??[]],{response:c,commit:u}=await this.sendWithClientToolsDiff(a,d,w=>{let f={...p,...w};return this.debug&&console.debug("[AgentWidgetClient] client token resume",f),fetch(s,{method:"POST",headers:l,body:JSON.stringify(f),signal:o?.signal})},{emptyMeansReplace:!0});return c.ok&&u(),c}return fetch(s,{method:"POST",headers:l,body:JSON.stringify(p),signal:o?.signal})}latestMentionContext(e){for(let n=e.length-1;n>=0;n--){let o=e[n];if(o.role==="user")return o.mentionContext&&Object.keys(o.mentionContext).length>0?{mentions:o.mentionContext}:null}return null}async buildContextAggregate(e){let n={};this.contextProviders.length&&await Promise.all(this.contextProviders.map(async r=>{try{let s=await r({messages:e,config:this.config});s&&typeof s=="object"&&Object.assign(n,s)}catch(s){typeof console<"u"&&console.warn("[AgentWidget] Context provider failed:",s)}}));let o=this.latestMentionContext(e);return o&&Object.assign(n,o),Object.keys(n).length?n:null}async buildAgentPayload(e){let n=this.routing().agentId;if(!this.config.agent&&!n)throw new Error("Agent configuration required for agent mode");let o=e.slice().filter(_i).filter(l=>l.role==="user"||l.role==="assistant"||l.role==="system").filter(l=>!l.variant||l.variant==="assistant").sort((l,p)=>{let d=new Date(l.createdAt).getTime(),c=new Date(p.createdAt).getTime();return d-c}).map(l=>({role:l.role,content:l.contentParts??l.llmContent??l.rawContent??l.content,createdAt:l.createdAt})),r={agent:this.config.agent??{agentId:n},messages:o,options:{streamResponse:!0,recordMode:"virtual",...this.config.agentOptions}},s=[...ta(this.config),...await this.webMcpBridge?.snapshotForDispatch()??[]];s.length>0&&(r.clientTools=s);let a=await this.buildContextAggregate(e);return a&&(r.context=a),r}async buildPayload(e){let n=e.slice().filter(_i).sort((l,p)=>{let d=new Date(l.createdAt).getTime(),c=new Date(p.createdAt).getTime();return d-c}).map(l=>({role:l.role,content:l.contentParts??l.llmContent??l.rawContent??l.content,createdAt:l.createdAt})),o=this.routing(),r={messages:n,...o.agentId?{agent:{agentId:o.agentId}}:o.flowId?{flowId:o.flowId}:{}};if(o.targetPayload)for(let[l,p]of Object.entries(o.targetPayload))l!=="messages"&&(r[l]=p);let s=[...ta(this.config),...await this.webMcpBridge?.snapshotForDispatch()??[]];s.length>0&&(r.clientTools=s);let a=await this.buildContextAggregate(e);if(a&&(r.context=a),this.requestMiddleware)try{let l=await this.requestMiddleware({payload:{...r},config:this.config});if(l&&typeof l=="object"){let p=l;return r.clientTools!==void 0&&!("clientTools"in p)&&(p.clientTools=r.clientTools),p}}catch(l){typeof console<"u"&&console.error("[AgentWidget] Request middleware error:",l)}return r}async handleCustomSSEEvent(e,n,o,r,s,a){if(!this.parseSSEEvent)return!1;try{let l=await this.parseSSEEvent(e);if(l===null)return!1;let p=c=>{let u={id:`assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,variant:"assistant",sequence:s(),...c!==void 0&&{partId:c}};return o.current=u,r(u),u},d=c=>o.current?o.current:p(c);if(l.text!==void 0){l.partId!==void 0&&a.current!==null&&l.partId!==a.current&&(o.current&&(o.current.streaming=!1,r(o.current)),p(l.partId)),l.partId!==void 0&&(a.current=l.partId);let c=d(l.partId);l.partId!==void 0&&!c.partId&&(c.partId=l.partId),c.content+=l.text,r(c)}return l.done&&(o.current&&(o.current.streaming=!1,r(o.current)),a.current=null,n({type:"status",status:"idle"})),l.error&&(a.current=null,n({type:"error",error:new Error(l.error)})),!0}catch(l){return typeof console<"u"&&console.error("[AgentWidget] parseSSEEvent error:",l),!1}}async streamResponse(e,n,o,r){let s=e.getReader(),a=new TextDecoder,l="",p=Date.now(),d=0,c=()=>p+d++,u=T=>{let O=T.reasoning?{...T.reasoning,chunks:[...T.reasoning.chunks]}:void 0,y=T.toolCall?{...T.toolCall,chunks:T.toolCall.chunks?[...T.toolCall.chunks]:void 0}:void 0,S=T.tools?T.tools.map(E=>({...E,chunks:E.chunks?[...E.chunks]:void 0})):void 0;return{...T,reasoning:O,toolCall:y,tools:S}},w=T=>{if(T.role!=="assistant"||T.variant)return!0;let O=Array.isArray(T.contentParts)&&T.contentParts.length>0,y=typeof T.rawContent=="string"&&T.rawContent.trim()!=="";return typeof T.content=="string"&&T.content.trim()!==""||O||y||!!T.stopReason},f=T=>{w(T)&&n({type:"message",message:u(T)})},v=null,C=null,I={current:null},B={current:null},k=null,M="",P=new Map,z=new Map,K=new Map,x=new Map,U=new Map,j={lastId:null,byStep:new Map},J={lastId:null,byCall:new Map},D=T=>{if(T==null)return null;try{return String(T)}catch{return null}},F=T=>D(T.stepId??T.step_id??T.step??T.parentId??T.flowStepId??T.flow_step_id),ie=T=>D(T.callId??T.call_id??T.requestId??T.request_id??T.toolCallId??T.tool_call_id??T.stepId??T.step_id),ge=o,Ce=!1,we=()=>{if(v)return v;let T,O="",y=k;return!Ce&&ge?(T=ge,Ce=!0,O=r??""):ge&&y?T=`${ge}_${y}`:T=`assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,v={id:T,role:"assistant",content:O,createdAt:new Date().toISOString(),streaming:!0,sequence:c()},f(v),v},ee=(T,O)=>{j.lastId=O,T&&j.byStep.set(T,O)},ce=(T,O)=>{let y=T.reasoningId??T.id,S=F(T);if(y){let W=String(y);return ee(S,W),W}if(S){let W=j.byStep.get(S);if(W)return j.lastId=W,W}if(j.lastId&&!O)return j.lastId;if(!O)return null;let E=`reason-${c()}`;return ee(S,E),E},Y=T=>{let O=x.get(T);if(O)return O;let y={id:`reason-${T}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,variant:"reasoning",sequence:c(),reasoning:{id:T,status:"streaming",chunks:[]}};return x.set(T,y),f(y),y},ae=(T,O)=>{J.lastId=O,T&&J.byCall.set(T,O)},Z=new Set,he=new Map,ye=new Set,pe=new Map,Te=T=>{if(!T)return!1;let O=T.replace(/_+/g,"_").replace(/^_|_$/g,"");return O==="emit_artifact_markdown"||O==="emit_artifact_component"},Ae=(T,O)=>{let y=T.toolId??T.id,S=ie(T);if(y){let W=String(y);return ae(S,W),W}if(S){let W=J.byCall.get(S);if(W)return J.lastId=W,W}if(J.lastId&&!O)return J.lastId;if(!O)return null;let E=`tool-${c()}`;return ae(S,E),E},$e=T=>{let O=U.get(T);if(O)return O;let y={id:`tool-${T}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,variant:"tool",sequence:c(),toolCall:{id:T,status:"pending"}};return U.set(T,y),f(y),y},Fe=T=>{if(typeof T=="number"&&Number.isFinite(T))return T;if(typeof T=="string"){let O=Number(T);if(!Number.isNaN(O)&&Number.isFinite(O))return O;let y=Date.parse(T);if(!Number.isNaN(y))return y}return Date.now()},ot=T=>{if(typeof T=="string")return T;if(T==null)return"";try{return JSON.stringify(T)}catch{return String(T)}},Qe=new Map,He=new Map,Ee=new Map,Xe=(T,O,y)=>{let S=Ee.get(T);S||(S=[],Ee.set(T,S));let E=0,W=S.length;for(;E<W;){let H=E+W>>>1;S[H].seq<O?E=H+1:W=H}S[E]?.seq===O?S[E]={seq:O,text:y}:S.splice(E,0,{seq:O,text:y});let q="";for(let H=0;H<S.length;H++)q+=S[H].text;return q},on=(T,O)=>{let y=ot(O),S=He.get(T.id),E=Dg(S,y);T.rawContent=E;let W=Qe.get(T.id),q=ke=>{let rt=T.content??"";ke.trim()!==""&&(rt.trim().length===0||ke.startsWith(rt)||ke.trimStart().startsWith(rt.trim()))&&(T.content=ke)},H=()=>{if(W){let ke=W.close?.();ke instanceof Promise&&ke.catch(()=>{})}Qe.delete(T.id),He.delete(T.id),T.streaming=!1,f(T)};if(!W){q(y),H();return}let $=Ur(E);if($!==null&&$.trim()!==""){q($),H();return}let se=ke=>{let rt=typeof ke=="string"?ke:ke?.text??null;if(rt!==null&&rt.trim()!=="")return rt;let V=W.getExtractedText();return V!==null&&V.trim()!==""?V:y},qe;try{qe=W.processChunk(E)}catch{q(y),H();return}if(qe instanceof Promise){qe.then(ke=>{q(se(ke)),H()}).catch(()=>{q(y),H()});return}q(se(qe)),H()},St=null,ht=(T,O,y,S)=>{T.rawContent=O,Qe.has(T.id)||Qe.set(T.id,this.createStreamParser());let E=Qe.get(T.id),W=O.trim().startsWith("{")||O.trim().startsWith("[");if(W&&He.set(T.id,O),E.__isPlainTextParser===!0){T.content=S!==void 0?O:T.content+y,He.delete(T.id),Qe.delete(T.id),T.rawContent=void 0,f(T);return}let H=E.processChunk(O);if(H instanceof Promise)H.then($=>{let se=typeof $=="string"?$:$?.text??null;se!==null&&se.trim()!==""?(T.content=se,f(T)):!W&&!O.trim().startsWith("<")&&(T.content=S!==void 0?O:T.content+y,He.delete(T.id),Qe.delete(T.id),T.rawContent=void 0,f(T))}).catch(()=>{T.content=S!==void 0?O:T.content+y,He.delete(T.id),Qe.delete(T.id),T.rawContent=void 0,f(T)});else{let $=typeof H=="string"?H:H?.text??null;$!==null&&$.trim()!==""?(T.content=$,f(T)):!W&&!O.trim().startsWith("<")&&(T.content=S!==void 0?O:T.content+y,He.delete(T.id),Qe.delete(T.id),T.rawContent=void 0,f(T))}},Be=(T,O)=>{let y=O??T.content;if(y==null||y===""){T.streaming=!1,f(T);return}let E=He.get(T.id)??ot(y);T.rawContent=E;let W=Qe.get(T.id),q=null,H=!1;if(W&&(q=W.getExtractedText(),q===null&&(q=Ur(E)),q===null)){let $=W.processChunk(E);$ instanceof Promise?(H=!0,$.then(se=>{let qe=typeof se=="string"?se:se?.text??null;qe!==null&&(T.content=qe,T.streaming=!1,Qe.delete(T.id),He.delete(T.id),f(T))}).catch(()=>{})):q=typeof $=="string"?$:$?.text??null}if(!H){q!==null&&q.trim()!==""?T.content=q:He.has(T.id)||(T.content=ot(y));let $=Qe.get(T.id);if($){let se=$.close?.();se instanceof Promise&&se.catch(()=>{}),Qe.delete(T.id)}He.delete(T.id),T.streaming=!1,f(T)}},me=(T,O,y)=>{let S=z.get(T);if(S)return S;let E={id:`nested-${O}-${T}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,sequence:c(),...y?{variant:y}:{},...y==="reasoning"?{reasoning:{id:T,status:"streaming",chunks:[]}}:{},agentMetadata:{parentToolId:O}};return z.set(T,E),f(E),E},Ke=[],Le,ue=new Map,le=0,be="agent",yt=!1,ve=null,de=null,un=new Map,X=this.config.iterationDisplay??"separate";for(Le=()=>{for(let T=0;T<Ke.length;T++){let O=Ke[T].payloadType,y=Ke[T].payload;if(!yt&&be!=="flow"&&typeof y.stepType=="string"&&(be="flow"),O==="reasoning_start"){let S=typeof y.id=="string"?y.id:null,E=typeof y.parentToolCallId=="string"&&y.parentToolCallId?y.parentToolCallId:null;if(S&&E){P.set(S,E),me(S,E,"reasoning");continue}let W=ce(y,!0)??`reason-${c()}`,q=Y(W);q.reasoning=q.reasoning??{id:W,status:"streaming",chunks:[]},q.reasoning.startedAt=q.reasoning.startedAt??Fe(y.startedAt??y.timestamp),q.reasoning.completedAt=void 0,q.reasoning.durationMs=void 0,(y.scope==="loop"||y.scope==="turn")&&(q.reasoning.scope=y.scope),q.streaming=!0,q.reasoning.status="streaming",f(q)}else if(O==="reasoning_delta"){let S=typeof y.id=="string"?y.id:null;if(S&&P.has(S)&&z.has(S)){let H=z.get(S),$=y.reasoningText??y.text??y.delta??"";$&&y.hidden!==!0&&H.reasoning&&(H.reasoning.chunks.push(String($)),f(H));continue}let E=ce(y,!1)??ce(y,!0)??`reason-${c()}`,W=Y(E);W.reasoning=W.reasoning??{id:E,status:"streaming",chunks:[]},W.reasoning.startedAt=W.reasoning.startedAt??Fe(y.startedAt??y.timestamp);let q=y.reasoningText??y.text??y.delta??"";if(q&&y.hidden!==!0){let H=typeof y.sequenceIndex=="number"?y.sequenceIndex:void 0;if(H!==void 0){let $=Xe(E,H,String(q));W.reasoning.chunks=[$]}else W.reasoning.chunks.push(String(q))}if(W.reasoning.status=y.done?"complete":"streaming",y.done){W.reasoning.completedAt=Fe(y.completedAt??y.timestamp);let H=W.reasoning.startedAt??Date.now();W.reasoning.durationMs=Math.max(0,(W.reasoning.completedAt??Date.now())-H)}W.streaming=W.reasoning.status!=="complete",f(W)}else if(O==="reasoning_complete"){let S=typeof y.id=="string"?y.id:null;if(S&&P.has(S)&&z.has(S)){let $=z.get(S);if($.reasoning){let se=typeof y.text=="string"?y.text:"";se&&$.reasoning.chunks.length===0&&$.reasoning.chunks.push(se),$.reasoning.status="complete",$.streaming=!1,f($)}P.delete(S),z.delete(S);continue}let E=ce(y,!1)??ce(y,!0)??`reason-${c()}`,W=typeof y.text=="string"?y.text:"";!x.get(E)&&(W||y.scope==="loop")&&Y(E);let q=x.get(E);if(q?.reasoning){(y.scope==="loop"||y.scope==="turn")&&(q.reasoning.scope=y.scope),W&&q.reasoning.chunks.length===0&&q.reasoning.chunks.push(W),q.reasoning.status="complete",q.reasoning.completedAt=Fe(y.completedAt??y.timestamp);let $=q.reasoning.startedAt??Date.now();q.reasoning.durationMs=Math.max(0,(q.reasoning.completedAt??Date.now())-$),q.streaming=!1,f(q)}let H=F(y);H&&j.byStep.delete(H)}else if(O==="tool_start"){v&&(v.streaming=!1,f(v),v=null),typeof y.iteration=="number"&&(le=y.iteration);let S=(typeof y.toolCallId=="string"?y.toolCallId:void 0)??Ae(y,!0)??`tool-${c()}`,E=y.toolName??y.name;if(Te(E)){Z.add(S);continue}ae(ie(y),S);let W=$e(S),q=W.toolCall??{id:S,status:"pending"};q.name=E??q.name,q.status="running",y.parameters!==void 0?q.args=y.parameters:y.args!==void 0&&(q.args=y.args),q.startedAt=q.startedAt??Fe(y.startedAt??y.timestamp),q.completedAt=void 0,q.durationMs=void 0,W.toolCall=q,W.streaming=!0,y.executionId&&(W.agentMetadata={executionId:y.executionId,iteration:y.iteration}),f(W)}else if(O==="tool_output_delta"){let S=Ae(y,!1)??Ae(y,!0)??`tool-${c()}`;if(Z.has(S))continue;let E=$e(S),W=E.toolCall??{id:S,status:"running"};W.startedAt=W.startedAt??Fe(y.startedAt??y.timestamp);let q=y.text??y.delta??y.message??"";q&&(W.chunks=W.chunks??[],W.chunks.push(String(q))),W.status="running",E.toolCall=W,E.streaming=!0;let H=y.agentContext;(H||y.executionId)&&(E.agentMetadata=E.agentMetadata??{executionId:H?.executionId??y.executionId,iteration:H?.iteration??y.iteration}),f(E)}else if(O==="tool_complete"){let S=Ae(y,!1)??Ae(y,!0)??`tool-${c()}`;if(Z.has(S)){Z.delete(S);continue}let E=$e(S),W=E.toolCall??{id:S,status:"running"};W.status="complete",y.result!==void 0&&(W.result=y.result),typeof y.duration=="number"&&(W.duration=y.duration),W.completedAt=Fe(y.completedAt??y.timestamp);let q=y.duration??y.executionTime;if(typeof q=="number")W.durationMs=q;else{let se=W.startedAt??Date.now();W.durationMs=Math.max(0,(W.completedAt??Date.now())-se)}E.toolCall=W,E.streaming=!1;let H=y.agentContext;(H||y.executionId)&&(E.agentMetadata=E.agentMetadata??{executionId:H?.executionId??y.executionId,iteration:H?.iteration??y.iteration}),f(E);let $=ie(y);$&&J.byCall.delete($)}else if(O==="await"&&y.toolName){let S=typeof y.toolCallId=="string"&&y.toolCallId.length>0?y.toolCallId:void 0,E=S??y.toolId??`local-${c()}`,W=$e(E),q=y.toolName,H=y.origin==="webmcp"&&!Ko(q)?`webmcp:${q}`:q,$=Ko(H),se=W.toolCall??{id:E,status:"pending"};se.name=H,se.args=y.parameters,se.status=$?"running":"complete",se.chunks=se.chunks??[],se.startedAt=se.startedAt??Fe(y.startedAt??y.timestamp??y.awaitedAt),$?(se.completedAt=void 0,se.duration=void 0,se.durationMs=void 0):se.completedAt=se.completedAt??se.startedAt,W.toolCall=se,W.streaming=!1,W.agentMetadata={...W.agentMetadata,executionId:y.executionId??W.agentMetadata?.executionId,awaitingLocalTool:!0,...S?{webMcpToolCallId:S}:{}},f(W)}else if(O==="text_start"){let S=typeof y.id=="string"?y.id:null,E=typeof y.parentToolCallId=="string"&&y.parentToolCallId?y.parentToolCallId:null;if(S&&E){P.set(S,E);continue}let W=v;W&&(be==="flow"?(Be(W),St=W):(W.streaming=!1,f(W)),v=null),k=typeof y.id=="string"?y.id:k,M=""}else if(O==="text_delta"){let S=typeof y.id=="string"?y.id:null,E=S?P.get(S):void 0;if(S&&E){let q=typeof y.delta=="string"?y.delta:"",H=(K.get(S)??"")+q;if(K.set(S,H),H.trim()==="")continue;let $=me(S,E);$.agentMetadata={...$.agentMetadata,executionId:y.executionId,parentToolId:E},ht($,H,q,void 0);continue}if(k=typeof y.id=="string"?y.id:k,be==="flow"){let q=typeof y.delta=="string"?y.delta:"";if(M+=q,M.trim()==="")continue;let H=we();H.agentMetadata={executionId:y.executionId,iteration:y.iteration},ht(H,M,q,void 0),C=H;continue}let W=we();W.content+=y.delta??"",W.agentMetadata={executionId:y.executionId,iteration:y.iteration,turnId:ve??void 0,agentName:de?.agentName},C=W,f(W)}else if(O==="text_complete"){let S=typeof y.id=="string"?y.id:null;if(S&&P.has(S)){let W=z.get(S);W&&Be(W),P.delete(S),K.delete(S),z.delete(S);continue}let E=v;E&&(be==="flow"?(Be(E),St=E):((E.content??"")===""&&typeof y.text=="string"&&(E.content=y.text),E.streaming=!1,f(E)),v=null),k=null,M=""}else if(O==="step_complete"){let S=y.stepType,E=y.executionType;if(S==="tool"||E==="context")continue;if(y.success===!1){let W=y.error,q=typeof W=="string"&&W!==""?W:W!=null&&typeof W=="object"&&Reflect.has(W,"message")?String(W.message??"Step failed"):"Step failed";n({type:"error",error:new Error(q)});let H=v;H&&H.streaming&&(H.streaming=!1,f(H)),n({type:"status",status:"idle"});continue}{let W=St;St=null;let q=y.stopReason,H=y.result?.response;if(W)q&&(W.stopReason=q),H!=null?on(W,H):W.streaming!==!1&&(Qe.delete(W.id),He.delete(W.id),W.streaming=!1,f(W));else{let $=H!=null&&H!=="";if($||q){let se=we();q&&(se.stopReason=q),$?Be(se,H):(se.streaming=!1,f(se))}}continue}}else if(O==="execution_start")be=y.kind==="flow"?"flow":"agent",yt=!0,be==="agent"&&(de={executionId:y.executionId,agentId:y.agentId??"virtual",agentName:y.agentName??"",status:"running",currentIteration:0,maxTurns:y.maxTurns??1,startedAt:Fe(y.startedAt)});else if(O==="turn_start"){let S=typeof y.iteration=="number"?y.iteration:le;if(S!==le){if(de&&(de.currentIteration=S),X==="separate"&&S>1){let E=v;E&&(E.streaming=!1,f(E),un.set(S-1,E),v=null)}le=S}ve=typeof y.id=="string"?y.id:null,C=null}else if(O==="tool_input_delta"){let S=y.toolCallId??J.lastId;if(S){let E=U.get(S);E?.toolCall&&(E.toolCall.chunks=E.toolCall.chunks??[],E.toolCall.chunks.push(y.delta??""),f(E))}}else{if(O==="tool_input_complete")continue;if(O==="turn_complete"){let S=y.stopReason,E=v??C;if(S&&E!==null){let W=y.id;(!W||E.agentMetadata?.turnId===W)&&(E.stopReason=S,f(E))}ve===y.id&&(ve=null)}else if(O==="media_start"){let S=String(y.id);ue.set(S,{mediaType:typeof y.mediaType=="string"?y.mediaType:void 0,role:typeof y.role=="string"?y.role:void 0,toolCallId:y.toolCallId,parts:[]})}else if(O==="media_delta"){let S=ue.get(String(y.id));S&&typeof y.delta=="string"&&S.parts.push(y.delta)}else if(O==="media_complete"){let S=String(y.id),E=ue.get(S);ue.delete(S);let W=(typeof y.mediaType=="string"?y.mediaType:void 0)??E?.mediaType??"application/octet-stream",q=typeof y.data=="string"?y.data:void 0,H=typeof y.url=="string"?y.url:E&&E.parts.length>0?E.parts.join(""):void 0,$=null;if(q)$={type:"media",data:q,mediaType:W};else if(H){let rt=W.toLowerCase();$={type:rt==="image"||rt.startsWith("image/")?"image-url":"file-url",url:H,mediaType:W}}let se=y.toolCallId??E?.toolCallId,qe=$?[$]:[],ke=[];for(let rt of qe){if(!rt||typeof rt!="object")continue;let V=rt,ze=typeof V.type=="string"?V.type:void 0,Se=typeof V.mediaType=="string"?V.mediaType.toLowerCase():"",We=null,Pe="";if(ze==="media"){let Je=typeof V.data=="string"?V.data:void 0;if(!Je)continue;Pe=Se.length>0?Se:"application/octet-stream",We=`data:${Pe};base64,${Je}`}else if(ze==="image-url"){let Je=typeof V.url=="string"?V.url:void 0;if(!Je)continue;Pe=Se,We=Je}else if(ze==="file-url"){let Je=typeof V.url=="string"?V.url:void 0;if(!Je)continue;Pe=Se,We=Je}else continue;if(We)if(ze==="image-url"||Pe.startsWith("image/"))ke.push({type:"image",image:We,...Pe.includes("/")?{mimeType:Pe}:{}});else if(Pe.startsWith("audio/"))ke.push({type:"audio",audio:We,mimeType:Pe});else if(Pe.startsWith("video/"))ke.push({type:"video",video:We,mimeType:Pe});else{let Je=Pe||"application/octet-stream";ke.push({type:"file",data:We,mimeType:Je,filename:Hg(Je)})}}if(ke.length>0){let rt=c(),V=se,Se={id:`agent-media-${typeof V=="string"&&V.length>0?`${V}-${rt}`:String(rt)}`,role:"assistant",content:"",contentParts:ke,createdAt:new Date().toISOString(),streaming:!1,sequence:rt,agentMetadata:{executionId:y.executionId,iteration:typeof y.iteration=="number"?y.iteration:le}};f(Se);let We=v;We&&(We.streaming=!1,f(We)),v=null,I.current=null}}else if(O==="execution_complete"){let S=y.kind??be;S==="agent"&&de&&(de.status=y.success?"complete":"error",de.completedAt=Fe(y.completedAt),de.stopReason=y.stopReason);let E=v;E&&(S==="flow"&&E.streaming!==!1?Be(E):(E.streaming=!1,f(E)),v=null),k=null,M="",St=null,n({type:"status",status:"idle",terminal:!0})}else if(O==="execution_error"){let S=typeof y.error=="string"?y.error:y.error?.message??"Execution error";n({type:"error",error:new Error(S)})}else if(O!=="ping"){if(O==="approval_start"){let S=y.approvalId??`approval-${c()}`,E={id:`approval-${S}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!1,variant:"approval",sequence:c(),approval:{id:S,status:"pending",agentId:de?.agentId??"virtual",executionId:y.executionId??de?.executionId??"",toolName:y.toolName??"",toolType:y.toolType,description:y.description??`Execute ${y.toolName??"tool"}`,...typeof y.reason=="string"&&y.reason?{reason:y.reason}:{},parameters:y.parameters}};f(E)}else if(O==="step_await"&&y.awaitReason==="approval_required"){let S=y.approvalId??`approval-${c()}`,E={id:`approval-${S}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!1,variant:"approval",sequence:c(),approval:{id:S,status:"pending",agentId:de?.agentId??"virtual",executionId:y.executionId??de?.executionId??"",toolName:y.toolName??"",toolType:y.toolType,description:y.description??`Execute ${y.toolName??"tool"}`,...typeof y.reason=="string"&&y.reason?{reason:y.reason}:{},parameters:y.parameters}};f(E)}else if(O==="approval_complete"){let S=y.approvalId;if(S){let W={id:`approval-${S}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!1,variant:"approval",sequence:c(),approval:{id:S,status:y.decision??"approved",agentId:de?.agentId??"virtual",executionId:y.executionId??de?.executionId??"",toolName:y.toolName??"",description:y.description??"",resolvedAt:Date.now()}};f(W)}}else if(O==="artifact_start"||O==="artifact_delta"||O==="artifact_update"||O==="artifact_complete"){if(O==="artifact_start"){let S=y.artifactType,E=String(y.id),W=typeof y.title=="string"?y.title:void 0,q=y.file,H;q&&typeof q=="object"&&!Array.isArray(q)&&typeof q.path=="string"&&typeof q.mimeType=="string"&&(H={path:q.path,mimeType:q.mimeType,...typeof q.language=="string"?{language:q.language}:{}}),n({type:"artifact_start",id:E,artifactType:S,title:W,component:typeof y.component=="string"?y.component:void 0,...H?{file:H}:{}});let $=y.props&&typeof y.props=="object"&&!Array.isArray(y.props)?{...y.props}:void 0;if(pe.set(E,{markdown:"",title:W,file:H,...$?{props:$}:{}}),!ye.has(E)){ye.add(E);let se=So(this.config.features?.artifacts,S),qe=typeof y.component=="string"?y.component:void 0,ke={id:`artifact-ref-${E}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,sequence:c(),rawContent:Js(se,{artifactId:E,title:W,artifactType:S,status:"streaming",...H?{file:H}:{},...qe?{component:qe}:{}})};he.set(E,ke),f(ke)}}else if(O==="artifact_delta"){let S=String(y.id),E=typeof y.delta=="string"?y.delta:String(y.delta??"");n({type:"artifact_delta",id:S,artDelta:E});let W=pe.get(S);W&&(W.markdown+=E)}else if(O==="artifact_update"){let S=y.props&&typeof y.props=="object"&&!Array.isArray(y.props)?y.props:{};n({type:"artifact_update",id:String(y.id),props:S,component:typeof y.component=="string"?y.component:void 0});let E=pe.get(String(y.id));E&&(E.props={...E.props??{},...S})}else if(O==="artifact_complete"){let S=String(y.id);n({type:"artifact_complete",id:S});let E=he.get(S);if(E){E.streaming=!1;try{let W=JSON.parse(E.rawContent??"{}");if(W.props){W.props.status="complete";let q=pe.get(S);q?.markdown&&(W.props.markdown=q.markdown),q?.file&&(W.props.file=q.file),W.component==="PersonaArtifactInline"&&q?.props&&Object.keys(q.props).length>0&&(W.props.componentProps=q.props)}E.rawContent=JSON.stringify(W)}catch{}pe.delete(S),f(E),he.delete(S)}}}else if(O==="transcript_insert"){let S=y.message;if(!S||typeof S!="object")continue;let E=String(S.id??`msg-${c()}`),W=S.role,H={id:E,role:W==="user"?"user":W==="system"?"system":"assistant",content:typeof S.content=="string"?S.content:"",rawContent:typeof S.rawContent=="string"?S.rawContent:void 0,createdAt:typeof S.createdAt=="string"?S.createdAt:new Date().toISOString(),streaming:S.streaming===!0,...typeof S.variant=="string"?{variant:S.variant}:{},sequence:c()};if(f(H),H.rawContent)try{let se=JSON.parse(H.rawContent)?.props?.artifactId;typeof se=="string"&&ye.add(se)}catch{}v=null,I.current=null,Qe.delete(E),He.delete(E)}else if(O==="error"){if(y.recoverable===!1&&y.error!=null&&y.error!==""){let S=typeof y.error=="string"?y.error:y.error?.message!=null?String(y.error.message):"Execution error";n({type:"error",error:new Error(S)});let E=v;E&&E.streaming&&(E.streaming=!1,f(E)),n({type:"status",status:"idle"})}}else if(O==="step_error"||O==="dispatch_error"||O==="flow_error"){let S=null;if(y.error instanceof Error)S=y.error;else if(O==="dispatch_error"){let E=y.message??y.error;E!=null&&E!==""&&(S=new Error(String(E)))}else{let E=y.error;typeof E=="string"&&E!==""?S=new Error(E):E!=null&&typeof E=="object"&&Reflect.has(E,"message")&&(S=new Error(String(E.message??E)))}if(S){n({type:"error",error:S});let E=v;E&&E.streaming&&(E.streaming=!1,f(E)),n({type:"status",status:"idle"})}}}}}Ke.length=0};;){let{done:T,value:O}=await s.read();if(T)break;l+=a.decode(O,{stream:!0});let y=l.split(`
|
|
11
|
+
`).replace(/\\r/g,"\r").replace(/\\t/g," ").replace(/\\"/g,'"').replace(/\\\\/g,"\\")}catch{return l[1]}return null};return{getExtractedText:()=>t,processChunk:async o=>{if(o.length<=e)return t!==null?{text:t,raw:o}:null;let r=o.trim();if(!r.startsWith("{")&&!r.startsWith("["))return null;let s=n(o);return s!==null&&(t=s),e=o.length,t!==null?{text:t,raw:o}:null},close:async()=>{}}},Ur=t=>{try{let e=JSON.parse(t);if(e&&typeof e=="object"&&typeof e.text=="string")return e.text}catch{return null}return null},Ld=()=>{let t={processChunk:e=>null,getExtractedText:()=>null};return t.__isPlainTextParser=!0,t},Pd=()=>{let t=Ig();return{processChunk:async e=>{let n=e.trim();return!n.startsWith("{")&&!n.startsWith("[")?null:t.processChunk(e)},getExtractedText:t.getExtractedText.bind(t),close:t.close?.bind(t)}},Id=()=>{let t=null,e=0;return{getExtractedText:()=>t,processChunk:n=>{let o=n.trim();if(!o.startsWith("{")&&!o.startsWith("["))return null;if(n.length<=e)return t!==null||t===""?{text:t||"",raw:n}:null;try{let r=Mg(n,Eg|kg);r&&typeof r=="object"&&(r.component&&typeof r.component=="string"?t=typeof r.text=="string"?Md(r.text):"":r.type==="init"&&r.form?t="":typeof r.text=="string"&&(t=Md(r.text)))}catch{}return e=n.length,t!==null?{text:t,raw:n}:null},close:()=>{}}};var Rd=()=>{let t=null;return{processChunk:e=>{if(!e.trim().startsWith("<"))return null;let o=e.match(/<text[^>]*>([\s\S]*?)<\/text>/);return o&&o[1]?(t=o[1],{text:t,raw:e}):null},getExtractedText:()=>t}};var Wd="4.12.0";var jr=Wd;var Wg="https://api.runtype.com/v1/dispatch",sa="https://api.runtype.com";function Hg(t){let e=t.toLowerCase(),o={"application/pdf":"pdf","application/json":"json","application/zip":"zip","text/plain":"txt","text/csv":"csv","text/markdown":"md"}[e];if(o)return`attachment.${o}`;let r=e.indexOf("/");if(r>0){let s=e.slice(r+1).split(";")[0]?.trim()??"";if(s&&s!=="octet-stream"&&/^[a-z0-9.+-]+$/i.test(s))return`attachment.${s}`}return"attachment"}var _i=t=>!!(t.contentParts&&t.contentParts.length>0||t.llmContent&&t.llmContent.trim().length>0||t.rawContent&&t.rawContent.trim().length>0||t.content&&t.content.trim().length>0);function Bg(t){switch(t){case"json":return Id;case"regex-json":return Pd;case"xml":return Rd;default:return Ld}}var Hd=t=>t.startsWith("{")||t.startsWith("[")||t.startsWith("<");function Dg(t,e){if(!t)return e;let n=t.trim(),o=e.trim();if(n.length===0)return e;if(o.length===0)return t;let r=Hd(n);if(!Hd(o))return t;if(!r||o===n||o.startsWith(n))return e;let a=Ur(t);return Ur(e)!==null&&a===null?e:t}var qr=class{constructor(e={}){this.config=e;this.clientSession=null;this.sessionInitPromise=null;this.lastSentClientToolsFingerprint=null;this.clientToolsFingerprintSessionId=null;this.sentNonEmptyClientToolsSessionId=null;if(e.target&&(e.agentId||e.flowId||e.agent))throw new Error("[Persona] `target` is mutually exclusive with `agentId`, `flowId`, and `agent`. Set only one routing field.");this.apiUrl=e.apiUrl??Wg,this.headers={"Content-Type":"application/json","X-Persona-Version":jr,...e.headers},this.debug=!!e.debug,this.createStreamParser=e.streamParser??Bg(e.parserType),this.contextProviders=e.contextProviders??[],this.requestMiddleware=e.requestMiddleware,this.customFetch=e.customFetch,this.parseSSEEvent=e.parseSSEEvent,this.getHeaders=e.getHeaders,this.webMcpBridge=e.webmcp?.enabled===!0?new Xs(e.webmcp):null}updateConfig(e){this.config=e}setSSEEventCallback(e){this.onSSEEvent=e}setWebMcpConfirmHandler(e){this.webMcpBridge?.setConfirmHandler(e)}isWebMcpOperational(){return this.webMcpBridge?.isOperational()===!0}executeWebMcpToolCall(e,n,o){return this.webMcpBridge?this.webMcpBridge.executeToolCall(e,n,o):null}getSSEEventCallback(){return this.onSSEEvent}isClientTokenMode(){return!!this.config.clientToken}routing(){let{agentId:e,flowId:n,target:o,targetProviders:r}=this.config;if(!o)return{agentId:e,flowId:n};let s=pd(o,r);return s.kind==="agentId"?{agentId:s.agentId}:s.kind==="flowId"?{flowId:s.flowId}:{targetPayload:s.payload}}isAgentMode(){return!!(this.config.agent||this.routing().agentId)}getClientApiUrl(e){return`${this.config.apiUrl?.replace(/\/+$/,"").replace(/\/v1\/dispatch$/,"")||sa}/v1/client/${e}`}getClientSession(){return this.clientSession}async initSession(){if(!this.isClientTokenMode())throw new Error("initSession() only available in client token mode");if(this.clientSession&&new Date<this.clientSession.expiresAt)return this.clientSession;if(this.sessionInitPromise)return this.sessionInitPromise;this.sessionInitPromise=this._doInitSession();try{let e=await this.sessionInitPromise;return this.clientSession=e,this.resetClientToolsFingerprint(),this.config.onSessionInit?.(e),e}finally{this.sessionInitPromise=null}}async _doInitSession(){let e=this.config.getStoredSessionId?.()||null,n=this.routing(),o=n.agentId??n.flowId,r={token:this.config.clientToken,...o&&{flowId:o},...e&&{sessionId:e}},s=await fetch(this.getClientApiUrl("init"),{method:"POST",headers:{"Content-Type":"application/json","X-Persona-Version":jr},body:JSON.stringify(r)});if(!s.ok){let l=await s.json().catch(()=>({error:"Session initialization failed"}));throw s.status===401?new Error(`Invalid client token: ${l.hint||l.error}`):s.status===403?new Error(`Origin not allowed: ${l.hint||l.error}`):new Error(l.error||"Failed to initialize session")}let a=await s.json();return this.config.setStoredSessionId&&this.config.setStoredSessionId(a.sessionId),{sessionId:a.sessionId,expiresAt:new Date(a.expiresAt),flow:a.flow,config:{welcomeMessage:a.config.welcomeMessage,placeholder:a.config.placeholder,theme:a.config.theme}}}clearClientSession(){this.clientSession=null,this.sessionInitPromise=null,this.resetClientToolsFingerprint()}resetClientToolsFingerprint(){this.lastSentClientToolsFingerprint=null,this.clientToolsFingerprintSessionId=null,this.sentNonEmptyClientToolsSessionId=null}getFeedbackApiUrl(){return`${this.config.apiUrl?.replace(/\/+$/,"").replace(/\/v1\/dispatch$/,"")||sa}/v1/client/feedback`}async sendFeedback(e){if(!this.isClientTokenMode())throw new Error("sendFeedback() only available in client token mode");if(!this.getClientSession())throw new Error("No active session. Please initialize session first.");if(["upvote","downvote","copy"].includes(e.type)&&!e.messageId)throw new Error(`messageId is required for ${e.type} feedback type`);if(e.type==="csat"&&(e.rating===void 0||e.rating<1||e.rating>5))throw new Error("CSAT rating must be between 1 and 5");if(e.type==="nps"&&(e.rating===void 0||e.rating<0||e.rating>10))throw new Error("NPS rating must be between 0 and 10");this.debug&&console.debug("[AgentWidgetClient] sending feedback",e);let r={...e,...this.config.clientToken&&{token:this.config.clientToken}},s=await fetch(this.getFeedbackApiUrl(),{method:"POST",headers:{"Content-Type":"application/json","X-Persona-Version":jr},body:JSON.stringify(r)});if(!s.ok){let a=await s.json().catch(()=>({error:"Feedback submission failed"}));throw s.status===401?(this.clientSession=null,this.config.onSessionExpired?.(),new Error("Session expired. Please refresh to continue.")):new Error(a.error||"Failed to submit feedback")}}async submitMessageFeedback(e,n){let o=this.getClientSession();if(!o)throw new Error("No active session. Please initialize session first.");return this.sendFeedback({sessionId:o.sessionId,messageId:e,type:n})}async submitCSATFeedback(e,n){let o=this.getClientSession();if(!o)throw new Error("No active session. Please initialize session first.");return this.sendFeedback({sessionId:o.sessionId,type:"csat",rating:e,comment:n})}async submitNPSFeedback(e,n){let o=this.getClientSession();if(!o)throw new Error("No active session. Please initialize session first.");return this.sendFeedback({sessionId:o.sessionId,type:"nps",rating:e,comment:n})}async dispatch(e,n){return e.signal?.throwIfAborted(),this.isClientTokenMode()?this.dispatchClientToken(e,n):this.isAgentMode()?this.dispatchAgent(e,n):this.dispatchProxy(e,n)}async dispatchClientToken(e,n){n({type:"status",status:"connecting"});try{let o=await this.initSession();if(new Date>=new Date(o.expiresAt.getTime()-6e4)){this.clearClientSession(),this.config.onSessionExpired?.();let d=new Error("Session expired. Please refresh to continue.");throw n({type:"error",error:d}),d}let r=await this.buildPayload(e.messages),s=r.metadata?Object.fromEntries(Object.entries(r.metadata).filter(([d])=>d!=="sessionId"&&d!=="session_id")):void 0,a={sessionId:o.sessionId,messages:e.messages.filter(_i).map(d=>({id:d.id,role:d.role,content:d.contentParts??d.llmContent??d.rawContent??d.content})),...e.assistantMessageId&&{assistantMessageId:e.assistantMessageId},...s&&Object.keys(s).length>0&&{metadata:s},...r.inputs&&Object.keys(r.inputs).length>0&&{inputs:r.inputs},...r.context&&{context:r.context}},{response:l,commit:p}=await this.sendWithClientToolsDiff(o.sessionId,r.clientTools,d=>{let c={...a,...d};return this.debug&&console.debug("[AgentWidgetClient] client token dispatch",c),fetch(this.getClientApiUrl("chat"),{method:"POST",headers:{"Content-Type":"application/json","X-Persona-Version":jr},body:JSON.stringify(c),signal:e.signal})});if(!l.ok){let d=await l.json().catch(()=>({error:"Chat request failed"}));if(l.status===401){this.clearClientSession(),this.config.onSessionExpired?.();let u=new Error("Session expired. Please refresh to continue.");throw n({type:"error",error:u}),u}if(l.status===429){let u=new Error(d.hint||"Message limit reached for this session.");throw n({type:"error",error:u}),u}let c=new Error(d.error||"Failed to send message");throw n({type:"error",error:c}),c}if(!l.body){let d=new Error("No response body received");throw n({type:"error",error:d}),d}p(),n({type:"status",status:"connected"});try{await this.streamResponse(l.body,n,e.assistantMessageId)}finally{n({type:"status",status:"idle"})}}catch(o){let r=o instanceof Error?o:new Error(String(o));throw!r.message.includes("Session expired")&&!r.message.includes("Message limit")&&n({type:"error",error:r}),r}}async dispatchProxy(e,n){n({type:"status",status:"connecting"});let o=await this.buildPayload(e.messages);this.debug&&console.debug("[AgentWidgetClient] dispatch payload",o);let r={...this.headers};if(this.getHeaders)try{let a=await this.getHeaders();r={...r,...a}}catch(a){typeof console<"u"&&console.error("[AgentWidget] getHeaders error:",a)}let s;if(this.customFetch)try{s=await this.customFetch(this.apiUrl,{method:"POST",headers:r,body:JSON.stringify(o),signal:e.signal},o)}catch(a){let l=a instanceof Error?a:new Error(String(a));throw n({type:"error",error:l}),l}else s=await fetch(this.apiUrl,{method:"POST",headers:r,body:JSON.stringify(o),signal:e.signal});if(!s.ok||!s.body){let a=new Error(`Chat backend request failed: ${s.status} ${s.statusText}`);throw n({type:"error",error:a}),a}n({type:"status",status:"connected"});try{await this.streamResponse(s.body,n)}finally{n({type:"status",status:"idle"})}}async dispatchAgent(e,n){n({type:"status",status:"connecting"});let o=await this.buildAgentPayload(e.messages);this.debug&&console.debug("[AgentWidgetClient] agent dispatch payload",o);let r={...this.headers};if(this.getHeaders)try{let a=await this.getHeaders();r={...r,...a}}catch(a){typeof console<"u"&&console.error("[AgentWidget] getHeaders error:",a)}let s;if(this.customFetch)try{s=await this.customFetch(this.apiUrl,{method:"POST",headers:r,body:JSON.stringify(o),signal:e.signal},o)}catch(a){let l=a instanceof Error?a:new Error(String(a));throw n({type:"error",error:l}),l}else s=await fetch(this.apiUrl,{method:"POST",headers:r,body:JSON.stringify(o),signal:e.signal});if(!s.ok||!s.body){let a=new Error(`Agent execution request failed: ${s.status} ${s.statusText}`);throw n({type:"error",error:a}),a}n({type:"status",status:"connected"});try{await this.streamResponse(s.body,n,e.assistantMessageId)}finally{n({type:"status",status:"idle"})}}async processStream(e,n,o,r){n({type:"status",status:"connected"});try{await this.streamResponse(e,n,o,r)}finally{n({type:"status",status:"idle"})}}async resolveApproval(e,n){let r=`${this.config.apiUrl?.replace(/\/+$/,"").replace(/\/v1\/dispatch$/,"")||sa}/v1/agents/${e.agentId}/approve`,s={"Content-Type":"application/json",...this.headers};return this.getHeaders&&Object.assign(s,await this.getHeaders()),fetch(r,{method:"POST",headers:s,body:JSON.stringify({executionId:e.executionId,approvalId:e.approvalId,decision:n,streamResponse:!0})})}async sendWithClientToolsDiff(e,n,o,r){let s=!!(n&&n.length>0),a=s?ld(n):void 0,l=this.clientToolsFingerprintSessionId===e,p=s&&l&&this.lastSentClientToolsFingerprint===a,d=!s&&r?.emptyMeansReplace===!0&&this.sentNonEmptyClientToolsSessionId===e,c=!1,u;for(let w=0;;w++){if(u=await o({...s&&(c||!p)&&n?{clientTools:n}:{},...d?{clientTools:[]}:{},...a?{clientToolsFingerprint:a}:{}}),u.status===409&&w===0&&s&&(await u.clone().json().catch(()=>null))?.error==="client_tools_resend_required"){c=!0,this.lastSentClientToolsFingerprint=null;continue}break}return{response:u,commit:()=>{this.lastSentClientToolsFingerprint=a??null,this.clientToolsFingerprintSessionId=e,s?this.sentNonEmptyClientToolsSessionId=e:d&&(this.sentNonEmptyClientToolsSessionId=null)}}}async resumeFlow(e,n,o){let r=this.isClientTokenMode(),s=r?this.getClientApiUrl("resume"):`${this.config.apiUrl?.replace(/\/+$/,"")||sa}/resume`,a;r&&(a=(await this.initSession()).sessionId);let l={"Content-Type":"application/json",...this.headers};this.getHeaders&&Object.assign(l,await this.getHeaders());let p={executionId:e,toolOutputs:n,streamResponse:o?.streamResponse??!0};if(a&&(p.sessionId=a),r&&a){let d=[...ta(this.config),...await this.webMcpBridge?.snapshotForDispatch()??[]],{response:c,commit:u}=await this.sendWithClientToolsDiff(a,d,w=>{let f={...p,...w};return this.debug&&console.debug("[AgentWidgetClient] client token resume",f),fetch(s,{method:"POST",headers:l,body:JSON.stringify(f),signal:o?.signal})},{emptyMeansReplace:!0});return c.ok&&u(),c}return fetch(s,{method:"POST",headers:l,body:JSON.stringify(p),signal:o?.signal})}latestMentionContext(e){for(let n=e.length-1;n>=0;n--){let o=e[n];if(o.role==="user")return o.mentionContext&&Object.keys(o.mentionContext).length>0?{mentions:o.mentionContext}:null}return null}async buildContextAggregate(e){let n={};this.contextProviders.length&&await Promise.all(this.contextProviders.map(async r=>{try{let s=await r({messages:e,config:this.config});s&&typeof s=="object"&&Object.assign(n,s)}catch(s){typeof console<"u"&&console.warn("[AgentWidget] Context provider failed:",s)}}));let o=this.latestMentionContext(e);return o&&Object.assign(n,o),Object.keys(n).length?n:null}async buildAgentPayload(e){let n=this.routing().agentId;if(!this.config.agent&&!n)throw new Error("Agent configuration required for agent mode");let o=e.slice().filter(_i).filter(l=>l.role==="user"||l.role==="assistant"||l.role==="system").filter(l=>!l.variant||l.variant==="assistant").sort((l,p)=>{let d=new Date(l.createdAt).getTime(),c=new Date(p.createdAt).getTime();return d-c}).map(l=>({role:l.role,content:l.contentParts??l.llmContent??l.rawContent??l.content,createdAt:l.createdAt})),r={agent:this.config.agent??{agentId:n},messages:o,options:{streamResponse:!0,recordMode:"virtual",...this.config.agentOptions}},s=[...ta(this.config),...await this.webMcpBridge?.snapshotForDispatch()??[]];s.length>0&&(r.clientTools=s);let a=await this.buildContextAggregate(e);return a&&(r.context=a),r}async buildPayload(e){let n=e.slice().filter(_i).sort((l,p)=>{let d=new Date(l.createdAt).getTime(),c=new Date(p.createdAt).getTime();return d-c}).map(l=>({role:l.role,content:l.contentParts??l.llmContent??l.rawContent??l.content,createdAt:l.createdAt})),o=this.routing(),r={messages:n,...o.agentId?{agent:{agentId:o.agentId}}:o.flowId?{flowId:o.flowId}:{}};if(o.targetPayload)for(let[l,p]of Object.entries(o.targetPayload))l!=="messages"&&(r[l]=p);let s=[...ta(this.config),...await this.webMcpBridge?.snapshotForDispatch()??[]];s.length>0&&(r.clientTools=s);let a=await this.buildContextAggregate(e);if(a&&(r.context=a),this.requestMiddleware)try{let l=await this.requestMiddleware({payload:{...r},config:this.config});if(l&&typeof l=="object"){let p=l;return r.clientTools!==void 0&&!("clientTools"in p)&&(p.clientTools=r.clientTools),p}}catch(l){typeof console<"u"&&console.error("[AgentWidget] Request middleware error:",l)}return r}async handleCustomSSEEvent(e,n,o,r,s,a){if(!this.parseSSEEvent)return!1;try{let l=await this.parseSSEEvent(e);if(l===null)return!1;let p=c=>{let u={id:`assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,variant:"assistant",sequence:s(),...c!==void 0&&{partId:c}};return o.current=u,r(u),u},d=c=>o.current?o.current:p(c);if(l.text!==void 0){l.partId!==void 0&&a.current!==null&&l.partId!==a.current&&(o.current&&(o.current.streaming=!1,r(o.current)),p(l.partId)),l.partId!==void 0&&(a.current=l.partId);let c=d(l.partId);l.partId!==void 0&&!c.partId&&(c.partId=l.partId),c.content+=l.text,r(c)}return l.done&&(o.current&&(o.current.streaming=!1,r(o.current)),a.current=null,n({type:"status",status:"idle"})),l.error&&(a.current=null,n({type:"error",error:new Error(l.error)})),!0}catch(l){return typeof console<"u"&&console.error("[AgentWidget] parseSSEEvent error:",l),!1}}async streamResponse(e,n,o,r){let s=e.getReader(),a=new TextDecoder,l="",p=Date.now(),d=0,c=()=>p+d++,u=T=>{let O=T.reasoning?{...T.reasoning,chunks:[...T.reasoning.chunks]}:void 0,y=T.toolCall?{...T.toolCall,chunks:T.toolCall.chunks?[...T.toolCall.chunks]:void 0}:void 0,S=T.tools?T.tools.map(E=>({...E,chunks:E.chunks?[...E.chunks]:void 0})):void 0;return{...T,reasoning:O,toolCall:y,tools:S}},w=T=>{if(T.role!=="assistant"||T.variant)return!0;let O=Array.isArray(T.contentParts)&&T.contentParts.length>0,y=typeof T.rawContent=="string"&&T.rawContent.trim()!=="";return typeof T.content=="string"&&T.content.trim()!==""||O||y||!!T.stopReason},f=T=>{w(T)&&n({type:"message",message:u(T)})},v=null,C=null,I={current:null},B={current:null},k=null,M="",P=new Map,z=new Map,K=new Map,x=new Map,U=new Map,j={lastId:null,byStep:new Map},J={lastId:null,byCall:new Map},D=T=>{if(T==null)return null;try{return String(T)}catch{return null}},F=T=>D(T.stepId??T.step_id??T.step??T.parentId??T.flowStepId??T.flow_step_id),ie=T=>D(T.callId??T.call_id??T.requestId??T.request_id??T.toolCallId??T.tool_call_id??T.stepId??T.step_id),ge=o,Ce=!1,we=()=>{if(v)return v;let T,O="",y=k;return!Ce&&ge?(T=ge,Ce=!0,O=r??""):ge&&y?T=`${ge}_${y}`:T=`assistant-${Date.now()}-${Math.random().toString(16).slice(2)}`,v={id:T,role:"assistant",content:O,createdAt:new Date().toISOString(),streaming:!0,sequence:c()},f(v),v},ee=(T,O)=>{j.lastId=O,T&&j.byStep.set(T,O)},ce=(T,O)=>{let y=T.reasoningId??T.id,S=F(T);if(y){let W=String(y);return ee(S,W),W}if(S){let W=j.byStep.get(S);if(W)return j.lastId=W,W}if(j.lastId&&!O)return j.lastId;if(!O)return null;let E=`reason-${c()}`;return ee(S,E),E},Y=T=>{let O=x.get(T);if(O)return O;let y={id:`reason-${T}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,variant:"reasoning",sequence:c(),reasoning:{id:T,status:"streaming",chunks:[]}};return x.set(T,y),f(y),y},ae=(T,O)=>{J.lastId=O,T&&J.byCall.set(T,O)},Z=new Set,he=new Map,ye=new Set,pe=new Map,Te=T=>{if(!T)return!1;let O=T.replace(/_+/g,"_").replace(/^_|_$/g,"");return O==="emit_artifact_markdown"||O==="emit_artifact_component"},Ae=(T,O)=>{let y=T.toolId??T.id,S=ie(T);if(y){let W=String(y);return ae(S,W),W}if(S){let W=J.byCall.get(S);if(W)return J.lastId=W,W}if(J.lastId&&!O)return J.lastId;if(!O)return null;let E=`tool-${c()}`;return ae(S,E),E},$e=T=>{let O=U.get(T);if(O)return O;let y={id:`tool-${T}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,variant:"tool",sequence:c(),toolCall:{id:T,status:"pending"}};return U.set(T,y),f(y),y},Fe=T=>{if(typeof T=="number"&&Number.isFinite(T))return T;if(typeof T=="string"){let O=Number(T);if(!Number.isNaN(O)&&Number.isFinite(O))return O;let y=Date.parse(T);if(!Number.isNaN(y))return y}return Date.now()},ot=T=>{if(typeof T=="string")return T;if(T==null)return"";try{return JSON.stringify(T)}catch{return String(T)}},Qe=new Map,He=new Map,Ee=new Map,Xe=(T,O,y)=>{let S=Ee.get(T);S||(S=[],Ee.set(T,S));let E=0,W=S.length;for(;E<W;){let H=E+W>>>1;S[H].seq<O?E=H+1:W=H}S[E]?.seq===O?S[E]={seq:O,text:y}:S.splice(E,0,{seq:O,text:y});let q="";for(let H=0;H<S.length;H++)q+=S[H].text;return q},on=(T,O)=>{let y=ot(O),S=He.get(T.id),E=Dg(S,y);T.rawContent=E;let W=Qe.get(T.id),q=ke=>{let rt=T.content??"";ke.trim()!==""&&(rt.trim().length===0||ke.startsWith(rt)||ke.trimStart().startsWith(rt.trim()))&&(T.content=ke)},H=()=>{if(W){let ke=W.close?.();ke instanceof Promise&&ke.catch(()=>{})}Qe.delete(T.id),He.delete(T.id),T.streaming=!1,f(T)};if(!W){q(y),H();return}let $=Ur(E);if($!==null&&$.trim()!==""){q($),H();return}let se=ke=>{let rt=typeof ke=="string"?ke:ke?.text??null;if(rt!==null&&rt.trim()!=="")return rt;let V=W.getExtractedText();return V!==null&&V.trim()!==""?V:y},qe;try{qe=W.processChunk(E)}catch{q(y),H();return}if(qe instanceof Promise){qe.then(ke=>{q(se(ke)),H()}).catch(()=>{q(y),H()});return}q(se(qe)),H()},St=null,ht=(T,O,y,S)=>{T.rawContent=O,Qe.has(T.id)||Qe.set(T.id,this.createStreamParser());let E=Qe.get(T.id),W=O.trim().startsWith("{")||O.trim().startsWith("[");if(W&&He.set(T.id,O),E.__isPlainTextParser===!0){T.content=S!==void 0?O:T.content+y,He.delete(T.id),Qe.delete(T.id),T.rawContent=void 0,f(T);return}let H=E.processChunk(O);if(H instanceof Promise)H.then($=>{let se=typeof $=="string"?$:$?.text??null;se!==null&&se.trim()!==""?(T.content=se,f(T)):!W&&!O.trim().startsWith("<")&&(T.content=S!==void 0?O:T.content+y,He.delete(T.id),Qe.delete(T.id),T.rawContent=void 0,f(T))}).catch(()=>{T.content=S!==void 0?O:T.content+y,He.delete(T.id),Qe.delete(T.id),T.rawContent=void 0,f(T)});else{let $=typeof H=="string"?H:H?.text??null;$!==null&&$.trim()!==""?(T.content=$,f(T)):!W&&!O.trim().startsWith("<")&&(T.content=S!==void 0?O:T.content+y,He.delete(T.id),Qe.delete(T.id),T.rawContent=void 0,f(T))}},Be=(T,O)=>{let y=O??T.content;if(y==null||y===""){T.streaming=!1,f(T);return}let E=He.get(T.id)??ot(y);T.rawContent=E;let W=Qe.get(T.id),q=null,H=!1;if(W&&(q=W.getExtractedText(),q===null&&(q=Ur(E)),q===null)){let $=W.processChunk(E);$ instanceof Promise?(H=!0,$.then(se=>{let qe=typeof se=="string"?se:se?.text??null;qe!==null&&(T.content=qe,T.streaming=!1,Qe.delete(T.id),He.delete(T.id),f(T))}).catch(()=>{})):q=typeof $=="string"?$:$?.text??null}if(!H){q!==null&&q.trim()!==""?T.content=q:He.has(T.id)||(T.content=ot(y));let $=Qe.get(T.id);if($){let se=$.close?.();se instanceof Promise&&se.catch(()=>{}),Qe.delete(T.id)}He.delete(T.id),T.streaming=!1,f(T)}},me=(T,O,y)=>{let S=z.get(T);if(S)return S;let E={id:`nested-${O}-${T}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,sequence:c(),...y?{variant:y}:{},...y==="reasoning"?{reasoning:{id:T,status:"streaming",chunks:[]}}:{},agentMetadata:{parentToolId:O}};return z.set(T,E),f(E),E},Ke=[],Le,ue=new Map,le=0,be="agent",yt=!1,ve=null,de=null,un=new Map,X=this.config.iterationDisplay??"separate";for(Le=()=>{for(let T=0;T<Ke.length;T++){let O=Ke[T].payloadType,y=Ke[T].payload;if(!yt&&be!=="flow"&&typeof y.stepType=="string"&&(be="flow"),O==="reasoning_start"){let S=typeof y.id=="string"?y.id:null,E=typeof y.parentToolCallId=="string"&&y.parentToolCallId?y.parentToolCallId:null;if(S&&E){P.set(S,E),me(S,E,"reasoning");continue}let W=ce(y,!0)??`reason-${c()}`,q=Y(W);q.reasoning=q.reasoning??{id:W,status:"streaming",chunks:[]},q.reasoning.startedAt=q.reasoning.startedAt??Fe(y.startedAt??y.timestamp),q.reasoning.completedAt=void 0,q.reasoning.durationMs=void 0,(y.scope==="loop"||y.scope==="turn")&&(q.reasoning.scope=y.scope),q.streaming=!0,q.reasoning.status="streaming",f(q)}else if(O==="reasoning_delta"){let S=typeof y.id=="string"?y.id:null;if(S&&P.has(S)&&z.has(S)){let H=z.get(S),$=y.reasoningText??y.text??y.delta??"";$&&y.hidden!==!0&&H.reasoning&&(H.reasoning.chunks.push(String($)),f(H));continue}let E=ce(y,!1)??ce(y,!0)??`reason-${c()}`,W=Y(E);W.reasoning=W.reasoning??{id:E,status:"streaming",chunks:[]},W.reasoning.startedAt=W.reasoning.startedAt??Fe(y.startedAt??y.timestamp);let q=y.reasoningText??y.text??y.delta??"";if(q&&y.hidden!==!0){let H=typeof y.sequenceIndex=="number"?y.sequenceIndex:void 0;if(H!==void 0){let $=Xe(E,H,String(q));W.reasoning.chunks=[$]}else W.reasoning.chunks.push(String(q))}if(W.reasoning.status=y.done?"complete":"streaming",y.done){W.reasoning.completedAt=Fe(y.completedAt??y.timestamp);let H=W.reasoning.startedAt??Date.now();W.reasoning.durationMs=Math.max(0,(W.reasoning.completedAt??Date.now())-H)}W.streaming=W.reasoning.status!=="complete",f(W)}else if(O==="reasoning_complete"){let S=typeof y.id=="string"?y.id:null;if(S&&P.has(S)&&z.has(S)){let $=z.get(S);if($.reasoning){let se=typeof y.text=="string"?y.text:"";se&&$.reasoning.chunks.length===0&&$.reasoning.chunks.push(se),$.reasoning.status="complete",$.streaming=!1,f($)}P.delete(S),z.delete(S);continue}let E=ce(y,!1)??ce(y,!0)??`reason-${c()}`,W=typeof y.text=="string"?y.text:"";!x.get(E)&&(W||y.scope==="loop")&&Y(E);let q=x.get(E);if(q?.reasoning){(y.scope==="loop"||y.scope==="turn")&&(q.reasoning.scope=y.scope),W&&q.reasoning.chunks.length===0&&q.reasoning.chunks.push(W),q.reasoning.status="complete",q.reasoning.completedAt=Fe(y.completedAt??y.timestamp);let $=q.reasoning.startedAt??Date.now();q.reasoning.durationMs=Math.max(0,(q.reasoning.completedAt??Date.now())-$),q.streaming=!1,f(q)}let H=F(y);H&&j.byStep.delete(H)}else if(O==="tool_start"){v&&(v.streaming=!1,f(v),v=null),typeof y.iteration=="number"&&(le=y.iteration);let S=(typeof y.toolCallId=="string"?y.toolCallId:void 0)??Ae(y,!0)??`tool-${c()}`,E=y.toolName??y.name;if(Te(E)){Z.add(S);continue}ae(ie(y),S);let W=$e(S),q=W.toolCall??{id:S,status:"pending"};q.name=E??q.name,q.status="running",y.parameters!==void 0?q.args=y.parameters:y.args!==void 0&&(q.args=y.args),q.startedAt=q.startedAt??Fe(y.startedAt??y.timestamp),q.completedAt=void 0,q.durationMs=void 0,W.toolCall=q,W.streaming=!0,y.executionId&&(W.agentMetadata={executionId:y.executionId,iteration:y.iteration}),f(W)}else if(O==="tool_output_delta"){let S=Ae(y,!1)??Ae(y,!0)??`tool-${c()}`;if(Z.has(S))continue;let E=$e(S),W=E.toolCall??{id:S,status:"running"};W.startedAt=W.startedAt??Fe(y.startedAt??y.timestamp);let q=y.text??y.delta??y.message??"";q&&(W.chunks=W.chunks??[],W.chunks.push(String(q))),W.status="running",E.toolCall=W,E.streaming=!0;let H=y.agentContext;(H||y.executionId)&&(E.agentMetadata=E.agentMetadata??{executionId:H?.executionId??y.executionId,iteration:H?.iteration??y.iteration}),f(E)}else if(O==="tool_complete"){let S=Ae(y,!1)??Ae(y,!0)??`tool-${c()}`;if(Z.has(S)){Z.delete(S);continue}let E=$e(S),W=E.toolCall??{id:S,status:"running"};W.status="complete",y.result!==void 0&&(W.result=y.result),typeof y.duration=="number"&&(W.duration=y.duration),W.completedAt=Fe(y.completedAt??y.timestamp);let q=y.duration??y.executionTime;if(typeof q=="number")W.durationMs=q;else{let se=W.startedAt??Date.now();W.durationMs=Math.max(0,(W.completedAt??Date.now())-se)}E.toolCall=W,E.streaming=!1;let H=y.agentContext;(H||y.executionId)&&(E.agentMetadata=E.agentMetadata??{executionId:H?.executionId??y.executionId,iteration:H?.iteration??y.iteration}),f(E);let $=ie(y);$&&J.byCall.delete($)}else if(O==="await"&&y.toolName){let S=typeof y.toolCallId=="string"&&y.toolCallId.length>0?y.toolCallId:void 0,E=S??y.toolId??`local-${c()}`,W=$e(E),q=y.toolName,H=y.origin==="webmcp"&&!Ko(q)?`webmcp:${q}`:q,$=Ko(H),se=W.toolCall??{id:E,status:"pending"};se.name=H,se.args=y.parameters,se.status=$?"running":"complete",se.chunks=se.chunks??[],se.startedAt=se.startedAt??Fe(y.startedAt??y.timestamp??y.awaitedAt),$?(se.completedAt=void 0,se.duration=void 0,se.durationMs=void 0):se.completedAt=se.completedAt??se.startedAt,W.toolCall=se,W.streaming=!1,W.agentMetadata={...W.agentMetadata,executionId:y.executionId??W.agentMetadata?.executionId,awaitingLocalTool:!0,...S?{webMcpToolCallId:S}:{}},f(W)}else if(O==="text_start"){let S=typeof y.id=="string"?y.id:null,E=typeof y.parentToolCallId=="string"&&y.parentToolCallId?y.parentToolCallId:null;if(S&&E){P.set(S,E);continue}let W=v;W&&(be==="flow"?(Be(W),St=W):(W.streaming=!1,f(W)),v=null),k=typeof y.id=="string"?y.id:k,M=""}else if(O==="text_delta"){let S=typeof y.id=="string"?y.id:null,E=S?P.get(S):void 0;if(S&&E){let q=typeof y.delta=="string"?y.delta:"",H=(K.get(S)??"")+q;if(K.set(S,H),H.trim()==="")continue;let $=me(S,E);$.agentMetadata={...$.agentMetadata,executionId:y.executionId,parentToolId:E},ht($,H,q,void 0);continue}if(k=typeof y.id=="string"?y.id:k,be==="flow"){let q=typeof y.delta=="string"?y.delta:"";if(M+=q,M.trim()==="")continue;let H=we();H.agentMetadata={executionId:y.executionId,iteration:y.iteration},ht(H,M,q,void 0),C=H;continue}let W=we();W.content+=y.delta??"",W.agentMetadata={executionId:y.executionId,iteration:y.iteration,turnId:ve??void 0,agentName:de?.agentName},C=W,f(W)}else if(O==="text_complete"){let S=typeof y.id=="string"?y.id:null;if(S&&P.has(S)){let W=z.get(S);W&&Be(W),P.delete(S),K.delete(S),z.delete(S);continue}let E=v;E&&(be==="flow"?(Be(E),St=E):((E.content??"")===""&&typeof y.text=="string"&&(E.content=y.text),E.streaming=!1,f(E)),v=null),k=null,M=""}else if(O==="step_complete"){let S=y.stepType,E=y.executionType;if(S==="tool"||E==="context")continue;if(y.success===!1){let W=y.error,q=typeof W=="string"&&W!==""?W:W!=null&&typeof W=="object"&&Reflect.has(W,"message")?String(W.message??"Step failed"):"Step failed";n({type:"error",error:new Error(q)});let H=v;H&&H.streaming&&(H.streaming=!1,f(H)),n({type:"status",status:"idle"});continue}{let W=St;St=null;let q=y.stopReason,H=y.result?.response;if(W)q&&(W.stopReason=q),H!=null?on(W,H):W.streaming!==!1&&(Qe.delete(W.id),He.delete(W.id),W.streaming=!1,f(W));else{let $=H!=null&&H!=="";if($||q){let se=we();q&&(se.stopReason=q),$?Be(se,H):(se.streaming=!1,f(se))}}continue}}else if(O==="execution_start")be=y.kind==="flow"?"flow":"agent",yt=!0,be==="agent"&&(de={executionId:y.executionId,agentId:y.agentId??"virtual",agentName:y.agentName??"",status:"running",currentIteration:0,maxTurns:y.maxTurns??1,startedAt:Fe(y.startedAt)});else if(O==="turn_start"){let S=typeof y.iteration=="number"?y.iteration:le;if(S!==le){if(de&&(de.currentIteration=S),X==="separate"&&S>1){let E=v;E&&(E.streaming=!1,f(E),un.set(S-1,E),v=null)}le=S}ve=typeof y.id=="string"?y.id:null,C=null}else if(O==="tool_input_delta"){let S=y.toolCallId??J.lastId;if(S){let E=U.get(S);E?.toolCall&&(E.toolCall.chunks=E.toolCall.chunks??[],E.toolCall.chunks.push(y.delta??""),f(E))}}else{if(O==="tool_input_complete")continue;if(O==="turn_complete"){let S=y.stopReason,E=v??C;if(S&&E!==null){let W=y.id;(!W||E.agentMetadata?.turnId===W)&&(E.stopReason=S,f(E))}ve===y.id&&(ve=null)}else if(O==="media_start"){let S=String(y.id);ue.set(S,{mediaType:typeof y.mediaType=="string"?y.mediaType:void 0,role:typeof y.role=="string"?y.role:void 0,toolCallId:y.toolCallId,parts:[]})}else if(O==="media_delta"){let S=ue.get(String(y.id));S&&typeof y.delta=="string"&&S.parts.push(y.delta)}else if(O==="media_complete"){let S=String(y.id),E=ue.get(S);ue.delete(S);let W=(typeof y.mediaType=="string"?y.mediaType:void 0)??E?.mediaType??"application/octet-stream",q=typeof y.data=="string"?y.data:void 0,H=typeof y.url=="string"?y.url:E&&E.parts.length>0?E.parts.join(""):void 0,$=null;if(q)$={type:"media",data:q,mediaType:W};else if(H){let rt=W.toLowerCase();$={type:rt==="image"||rt.startsWith("image/")?"image-url":"file-url",url:H,mediaType:W}}let se=y.toolCallId??E?.toolCallId,qe=$?[$]:[],ke=[];for(let rt of qe){if(!rt||typeof rt!="object")continue;let V=rt,ze=typeof V.type=="string"?V.type:void 0,Se=typeof V.mediaType=="string"?V.mediaType.toLowerCase():"",We=null,Pe="";if(ze==="media"){let Je=typeof V.data=="string"?V.data:void 0;if(!Je)continue;Pe=Se.length>0?Se:"application/octet-stream",We=`data:${Pe};base64,${Je}`}else if(ze==="image-url"){let Je=typeof V.url=="string"?V.url:void 0;if(!Je)continue;Pe=Se,We=Je}else if(ze==="file-url"){let Je=typeof V.url=="string"?V.url:void 0;if(!Je)continue;Pe=Se,We=Je}else continue;if(We)if(ze==="image-url"||Pe.startsWith("image/"))ke.push({type:"image",image:We,...Pe.includes("/")?{mimeType:Pe}:{}});else if(Pe.startsWith("audio/"))ke.push({type:"audio",audio:We,mimeType:Pe});else if(Pe.startsWith("video/"))ke.push({type:"video",video:We,mimeType:Pe});else{let Je=Pe||"application/octet-stream";ke.push({type:"file",data:We,mimeType:Je,filename:Hg(Je)})}}if(ke.length>0){let rt=c(),V=se,Se={id:`agent-media-${typeof V=="string"&&V.length>0?`${V}-${rt}`:String(rt)}`,role:"assistant",content:"",contentParts:ke,createdAt:new Date().toISOString(),streaming:!1,sequence:rt,agentMetadata:{executionId:y.executionId,iteration:typeof y.iteration=="number"?y.iteration:le}};f(Se);let We=v;We&&(We.streaming=!1,f(We)),v=null,I.current=null}}else if(O==="execution_complete"){let S=y.kind??be;S==="agent"&&de&&(de.status=y.success?"complete":"error",de.completedAt=Fe(y.completedAt),de.stopReason=y.stopReason);let E=v;E&&(S==="flow"&&E.streaming!==!1?Be(E):(E.streaming=!1,f(E)),v=null),k=null,M="",St=null,n({type:"status",status:"idle",terminal:!0})}else if(O==="execution_error"){let S=typeof y.error=="string"?y.error:y.error?.message??"Execution error";n({type:"error",error:new Error(S)})}else if(O!=="ping"){if(O==="approval_start"){let S=y.approvalId??`approval-${c()}`,E={id:`approval-${S}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!1,variant:"approval",sequence:c(),approval:{id:S,status:"pending",agentId:de?.agentId??"virtual",executionId:y.executionId??de?.executionId??"",toolName:y.toolName??"",toolType:y.toolType,description:y.description??`Execute ${y.toolName??"tool"}`,...typeof y.reason=="string"&&y.reason?{reason:y.reason}:{},parameters:y.parameters}};f(E)}else if(O==="step_await"&&y.awaitReason==="approval_required"){let S=y.approvalId??`approval-${c()}`,E={id:`approval-${S}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!1,variant:"approval",sequence:c(),approval:{id:S,status:"pending",agentId:de?.agentId??"virtual",executionId:y.executionId??de?.executionId??"",toolName:y.toolName??"",toolType:y.toolType,description:y.description??`Execute ${y.toolName??"tool"}`,...typeof y.reason=="string"&&y.reason?{reason:y.reason}:{},parameters:y.parameters}};f(E)}else if(O==="approval_complete"){let S=y.approvalId;if(S){let W={id:`approval-${S}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!1,variant:"approval",sequence:c(),approval:{id:S,status:y.decision??"approved",agentId:de?.agentId??"virtual",executionId:y.executionId??de?.executionId??"",toolName:y.toolName??"",description:y.description??"",resolvedAt:Date.now()}};f(W)}}else if(O==="artifact_start"||O==="artifact_delta"||O==="artifact_update"||O==="artifact_complete"){if(O==="artifact_start"){let S=y.artifactType,E=String(y.id),W=typeof y.title=="string"?y.title:void 0,q=y.file,H;q&&typeof q=="object"&&!Array.isArray(q)&&typeof q.path=="string"&&typeof q.mimeType=="string"&&(H={path:q.path,mimeType:q.mimeType,...typeof q.language=="string"?{language:q.language}:{}}),n({type:"artifact_start",id:E,artifactType:S,title:W,component:typeof y.component=="string"?y.component:void 0,...H?{file:H}:{}});let $=y.props&&typeof y.props=="object"&&!Array.isArray(y.props)?{...y.props}:void 0;if(pe.set(E,{markdown:"",title:W,file:H,...$?{props:$}:{}}),!ye.has(E)){ye.add(E);let se=So(this.config.features?.artifacts,S),qe=typeof y.component=="string"?y.component:void 0,ke={id:`artifact-ref-${E}`,role:"assistant",content:"",createdAt:new Date().toISOString(),streaming:!0,sequence:c(),rawContent:Js(se,{artifactId:E,title:W,artifactType:S,status:"streaming",...H?{file:H}:{},...qe?{component:qe}:{}})};he.set(E,ke),f(ke)}}else if(O==="artifact_delta"){let S=String(y.id),E=typeof y.delta=="string"?y.delta:String(y.delta??"");n({type:"artifact_delta",id:S,artDelta:E});let W=pe.get(S);W&&(W.markdown+=E)}else if(O==="artifact_update"){let S=y.props&&typeof y.props=="object"&&!Array.isArray(y.props)?y.props:{};n({type:"artifact_update",id:String(y.id),props:S,component:typeof y.component=="string"?y.component:void 0});let E=pe.get(String(y.id));E&&(E.props={...E.props??{},...S})}else if(O==="artifact_complete"){let S=String(y.id);n({type:"artifact_complete",id:S});let E=he.get(S);if(E){E.streaming=!1;try{let W=JSON.parse(E.rawContent??"{}");if(W.props){W.props.status="complete";let q=pe.get(S);q?.markdown&&(W.props.markdown=q.markdown),q?.file&&(W.props.file=q.file),W.component==="PersonaArtifactInline"&&q?.props&&Object.keys(q.props).length>0&&(W.props.componentProps=q.props)}E.rawContent=JSON.stringify(W)}catch{}pe.delete(S),f(E),he.delete(S)}}}else if(O==="transcript_insert"){let S=y.message;if(!S||typeof S!="object")continue;let E=String(S.id??`msg-${c()}`),W=S.role,H={id:E,role:W==="user"?"user":W==="system"?"system":"assistant",content:typeof S.content=="string"?S.content:"",rawContent:typeof S.rawContent=="string"?S.rawContent:void 0,createdAt:typeof S.createdAt=="string"?S.createdAt:new Date().toISOString(),streaming:S.streaming===!0,...typeof S.variant=="string"?{variant:S.variant}:{},sequence:c()};if(f(H),H.rawContent)try{let se=JSON.parse(H.rawContent)?.props?.artifactId;typeof se=="string"&&ye.add(se)}catch{}v=null,I.current=null,Qe.delete(E),He.delete(E)}else if(O==="error"){if(y.recoverable===!1&&y.error!=null&&y.error!==""){let S=typeof y.error=="string"?y.error:y.error?.message!=null?String(y.error.message):"Execution error";n({type:"error",error:new Error(S)});let E=v;E&&E.streaming&&(E.streaming=!1,f(E)),n({type:"status",status:"idle"})}}else if(O==="step_error"||O==="dispatch_error"||O==="flow_error"){let S=null;if(y.error instanceof Error)S=y.error;else if(O==="dispatch_error"){let E=y.message??y.error;E!=null&&E!==""&&(S=new Error(String(E)))}else{let E=y.error;typeof E=="string"&&E!==""?S=new Error(E):E!=null&&typeof E=="object"&&Reflect.has(E,"message")&&(S=new Error(String(E.message??E)))}if(S){n({type:"error",error:S});let E=v;E&&E.streaming&&(E.streaming=!1,f(E)),n({type:"status",status:"idle"})}}}}}Ke.length=0};;){let{done:T,value:O}=await s.read();if(T)break;l+=a.decode(O,{stream:!0});let y=l.split(`
|
|
12
12
|
|
|
13
13
|
`);l=y.pop()??"";for(let S of y){let E=S.split(`
|
|
14
14
|
`),W="message",q="",H=null;for(let ke of E)ke.startsWith("event:")?W=ke.replace("event:","").trim():ke.startsWith("data:")?q+=ke.replace("data:","").trim():ke.startsWith("id:")&&(H=ke.slice(3).trim());let $=()=>{H!==null&&H!==""&&n({type:"cursor",id:H})};if(!q){$();continue}let se;try{se=JSON.parse(q)}catch(ke){n({type:"error",error:ke instanceof Error?ke:new Error("Failed to parse chat stream payload")});continue}let qe=W!=="message"?W:se.type??"message";if(this.onSSEEvent?.(qe,se),this.parseSSEEvent){I.current=v;let ke=await this.handleCustomSSEEvent(se,n,I,f,c,B);if(I.current&&I.current!==v&&(v=I.current),ke){$();continue}}Ke.push({payloadType:qe,payload:se}),Le(),$()}}Le()}};function aa(){let t=Date.now().toString(36),e=Math.random().toString(36).substring(2,10);return`usr_${t}_${e}`}function Yo(){let t=Date.now().toString(36),e=Math.random().toString(36).substring(2,10);return`ast_${t}_${e}`}var ia="[Image]";function Bd(t){return typeof t=="string"?!1:t.some(e=>e.type==="image")}function Zo(t){return{type:"text",text:t}}var Dd=["image/png","image/jpeg","image/gif","image/webp","image/svg+xml","image/bmp"],Fg=["application/pdf","text/plain","text/markdown","text/csv","application/msword","application/vnd.openxmlformats-officedocument.wordprocessingml.document","application/vnd.ms-excel","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet","application/json"],Fn=[...Dd,...Fg];function Ng(t){return Dd.includes(t)||t.startsWith("image/")}function la(t){return Ng(t.type)}async function Fd(t){return new Promise((e,n)=>{let o=new FileReader;o.onload=()=>{let r=o.result;la(t)?e({type:"image",image:r,mimeType:t.type,alt:t.name}):e({type:"file",data:r,mimeType:t.type,filename:t.name})},o.onerror=()=>n(new Error("Failed to read file")),o.readAsDataURL(t)})}function Nd(t,e=Fn,n=10*1024*1024){return e.includes(t.type)?t.size>n?{valid:!1,error:`File too large. Maximum size: ${Math.round(n/1048576)}MB`}:{valid:!0}:{valid:!1,error:`Invalid file type "${t.type}". Accepted types: ${e.join(", ")}`}}function Og(t){let e=t.split(".");return e.length>1?e.pop().toLowerCase():""}function Od(t,e){let n=Og(e).toUpperCase();return{"application/pdf":"PDF","text/plain":"TXT","text/markdown":"MD","text/csv":"CSV","application/msword":"DOC","application/vnd.openxmlformats-officedocument.wordprocessingml.document":"DOCX","application/vnd.ms-excel":"XLS","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":"XLSX","application/json":"JSON"}[t]||n||"FILE"}var _d=16e3,_g=24e3,$g=4096,zg=1380533830;function Ug(t){return t.byteLength>=44&&new DataView(t).getUint32(0,!1)===zg?new Uint8Array(t,44):new Uint8Array(t)}function jg(t){let e=t.replace(/\/+$/,"");return/^wss?:\/\//i.test(e)?e:/^https?:\/\//i.test(e)?e.replace(/^http/i,"ws"):`${typeof window<"u"&&window.location?.protocol==="https:"?"wss:":"ws:"}//${e}`}var Vr=class{constructor(e){this.config=e;this.type="runtype";this.ws=null;this.captureContext=null;this.mediaStream=null;this.sourceNode=null;this.processor=null;this.playback=null;this.callLive=!1;this.isSpeaking=!1;this.callGeneration=0;this.intentionalClose=!1;this.resultCallbacks=[];this.errorCallbacks=[];this.statusCallbacks=[];this.transcriptCallbacks=[];this.metricsCallbacks=[]}async connect(){}async startListening(){if(this.callLive)return;let e=this.config?.agentId,n=this.config?.clientToken,o=this.config?.host;if(!e)throw new Error("Runtype voice requires an agentId");if(!n)throw new Error("Runtype voice requires a clientToken");if(!o)throw new Error("Runtype voice requires a host (or widget apiUrl)");let r=++this.callGeneration;this.intentionalClose=!1,this.callLive=!0;try{let s=await navigator.mediaDevices.getUserMedia({audio:{sampleRate:_d,channelCount:1,echoCancellation:!0}});if(r!==this.callGeneration){s.getTracks().forEach(u=>u.stop());return}this.mediaStream=s;let a=window.AudioContext||window.webkitAudioContext,l=new a({sampleRate:_d});l.state==="suspended"&&await l.resume().catch(()=>{}),this.captureContext=l;let p=this.config?.createPlaybackEngine?await this.config.createPlaybackEngine():new qc(_g);if(r!==this.callGeneration){p.destroy(),s.getTracks().forEach(u=>u.stop()),l.close().catch(()=>{});return}this.playback=p,p.onFinished(()=>{r===this.callGeneration&&(this.isSpeaking=!1,this.ws&&this.ws.readyState===WebSocket.OPEN&&this.emitStatus("listening"))});let d=`${jg(o)}/ws/agents/${encodeURIComponent(e)}/voice`,c=new WebSocket(d,["runtype.bearer",n]);c.binaryType="arraybuffer",this.ws=c,c.onopen=()=>{r===this.callGeneration&&(this.emitStatus("listening"),this.startCapture(l,s,c,r))},c.onmessage=u=>this.handleMessage(u,r),c.onerror=()=>{r===this.callGeneration&&(this.emitError(new Error("Voice connection failed")),this.emitStatus("error"),this.cleanup())},c.onclose=u=>{if(this.intentionalClose){this.intentionalClose=!1;return}if(r===this.callGeneration){if(u.code!==1e3){let w=u.code?` (code ${u.code})`:"";this.emitError(new Error(`Voice connection closed${w}`)),this.emitStatus("error")}else this.emitStatus("idle");this.cleanup()}}}catch(s){throw this.cleanup(),this.emitError(s),this.emitStatus("error"),s}}async stopListening(){this.cleanup(),this.emitStatus("idle")}async disconnect(){this.cleanup(),this.emitStatus("disconnected"),this.resultCallbacks=[],this.errorCallbacks=[],this.statusCallbacks=[],this.transcriptCallbacks=[],this.metricsCallbacks=[]}stopPlayback(){this.playback&&this.playback.flush(),this.isSpeaking=!1,this.ws&&this.ws.readyState===WebSocket.OPEN&&this.emitStatus("listening")}getInterruptionMode(){return"barge-in"}isBargeInActive(){return this.callLive}async deactivateBargeIn(){this.cleanup(),this.emitStatus("idle")}startCapture(e,n,o,r){let s=e.createMediaStreamSource(n);this.sourceNode=s;let a=e.createScriptProcessor($g,1,1);this.processor=a,a.onaudioprocess=l=>{if(r!==this.callGeneration||o.readyState!==WebSocket.OPEN)return;let p=l.inputBuffer.getChannelData(0),d=new Int16Array(p.length);for(let c=0;c<p.length;c++){let u=Math.max(-1,Math.min(1,p[c]));d[c]=u<0?u*32768:u*32767}o.send(d.buffer)},s.connect(a),a.connect(e.destination)}handleMessage(e,n){if(n!==this.callGeneration)return;if(e.data instanceof ArrayBuffer){this.handleAudioFrame(e.data,n);return}let o;try{o=JSON.parse(e.data)}catch{return}switch(o.type){case"transcript_interim":this.emitStatus("listening"),this.emitTranscript("user",o.text??"",!1);break;case"transcript_final":{let r=o.role==="assistant"?"assistant":"user";this.emitStatus(r==="user"?"processing":"speaking"),this.emitTranscript(r,o.text??"",!0);break}case"audio_end":this.playback?this.playback.markStreamEnd():(this.isSpeaking=!1,this.emitStatus("listening"));break;case"metrics":this.emitMetrics({llmMs:o.llm_ms,ttsMs:o.tts_ms,firstAudioMs:o.first_audio_ms,totalMs:o.total_ms});break;case"error":this.emitError(new Error(o.error||"Voice error")),this.emitStatus("error");break}}handleAudioFrame(e,n){if(n!==this.callGeneration||!this.playback)return;let o=Ug(e);o.length!==0&&(this.isSpeaking||(this.isSpeaking=!0,this.emitStatus("speaking")),this.playback.enqueue(o))}cleanup(){if(this.callGeneration+=1,this.callLive=!1,this.isSpeaking=!1,this.processor&&(this.processor.onaudioprocess=null,this.processor.disconnect(),this.processor=null),this.sourceNode&&(this.sourceNode.disconnect(),this.sourceNode=null),this.mediaStream&&(this.mediaStream.getTracks().forEach(e=>e.stop()),this.mediaStream=null),this.captureContext&&(this.captureContext.close().catch(()=>{}),this.captureContext=null),this.playback&&(this.playback.destroy(),this.playback=null),this.ws){this.intentionalClose=!0;try{this.ws.close(1e3,"client ended call")}catch{}this.ws=null}}onResult(e){this.resultCallbacks.push(e)}onError(e){this.errorCallbacks.push(e)}onStatusChange(e){this.statusCallbacks.push(e)}onTranscript(e){this.transcriptCallbacks.push(e)}onMetrics(e){this.metricsCallbacks.push(e)}emitStatus(e){this.statusCallbacks.forEach(n=>n(e))}emitError(e){this.errorCallbacks.forEach(n=>n(e))}emitTranscript(e,n,o){this.transcriptCallbacks.forEach(r=>r(e,n,o))}emitMetrics(e){this.metricsCallbacks.forEach(n=>n(e))}};var Eo=class{constructor(e={}){this.config=e;this.type="browser";this.recognition=null;this.resultCallbacks=[];this.errorCallbacks=[];this.statusCallbacks=[];this.isListening=!1;this.w=typeof window<"u"?window:void 0}async connect(){this.statusCallbacks.forEach(e=>e("connected"))}async startListening(){try{if(this.isListening)throw new Error("Already listening");if(!this.w)throw new Error("Window object not available");let e=this.w.SpeechRecognition||this.w.webkitSpeechRecognition;if(!e)throw new Error("Browser speech recognition not supported");this.recognition=new e,this.recognition.lang=this.config?.language||"en-US",this.recognition.continuous=this.config?.continuous||!1,this.recognition.interimResults=!0,this.recognition.onresult=n=>{let o=Array.from(n.results).map(s=>s[0]).map(s=>s.transcript).join(""),r=n.results[n.results.length-1].isFinal;this.resultCallbacks.forEach(s=>s({text:o,confidence:r?.8:.5,provider:"browser"})),r&&!this.config?.continuous&&this.stopListening()},this.recognition.onerror=n=>{this.errorCallbacks.forEach(o=>o(new Error(n.error))),this.statusCallbacks.forEach(o=>o("error"))},this.recognition.onstart=()=>{this.isListening=!0,this.statusCallbacks.forEach(n=>n("listening"))},this.recognition.onend=()=>{this.isListening=!1,this.statusCallbacks.forEach(n=>n("idle"))},this.recognition.start()}catch(e){throw this.errorCallbacks.forEach(n=>n(e)),this.statusCallbacks.forEach(n=>n("error")),e}}async stopListening(){this.recognition&&(this.recognition.stop(),this.recognition=null),this.isListening=!1,this.statusCallbacks.forEach(e=>e("idle"))}onResult(e){this.resultCallbacks.push(e)}onError(e){this.errorCallbacks.push(e)}onStatusChange(e){this.statusCallbacks.push(e)}async disconnect(){await this.stopListening(),this.statusCallbacks.forEach(e=>e("disconnected"))}static isSupported(){return"SpeechRecognition"in window||"webkitSpeechRecognition"in window}};function er(t){switch(t.type){case"runtype":if(!t.runtype)throw new Error("Runtype voice provider requires configuration");return new Vr(t.runtype);case"browser":if(!Eo.isSupported())throw new Error("Browser speech recognition not supported");return new Eo(t.browser||{});case"custom":{let e=t.custom;if(!e)throw new Error("Custom voice provider requires a `custom` provider instance or factory");let n=typeof e=="function"?e():e;if(!n||typeof n.startListening!="function")throw new Error("Custom voice provider `custom` must be a VoiceProvider (or a factory returning one)");return n}default:throw new Error(`Unknown voice provider type: ${t.type}`)}}function $d(t){if(t?.type==="custom"&&t.custom)return er({type:"custom",custom:t.custom});if(t?.type==="runtype"&&t.runtype)return er({type:"runtype",runtype:t.runtype});if(Eo.isSupported())return er({type:"browser",browser:t?.browser||{language:"en-US"}});throw new Error("No supported voice providers available")}function $i(t){try{return $d(t),!0}catch{return!1}}function ca(t){let e=["Microsoft Jenny Online (Natural) - English (United States)","Microsoft Aria Online (Natural) - English (United States)","Microsoft Guy Online (Natural) - English (United States)","Google US English","Google UK English Female","Ava (Premium)","Evan (Enhanced)","Samantha (Enhanced)","Samantha","Daniel","Karen","Microsoft David Desktop - English (United States)","Microsoft Zira Desktop - English (United States)"];for(let n of e){let o=t.find(r=>r.name===n);if(o)return o}return t.find(n=>n.lang.startsWith("en"))??t[0]}var tr=class t{constructor(e={}){this.options=e;this.id="browser";this.supportsPause=!0}static isSupported(){return typeof window<"u"&&"speechSynthesis"in window}speak(e,n){if(!t.isSupported()){n.onError?.(new Error("Web Speech API is unavailable"));return}let o=window.speechSynthesis;o.cancel();let r=new SpeechSynthesisUtterance(e.text),s=o.getVoices();if(e.voice){let a=s.find(l=>l.name===e.voice);a&&(r.voice=a)}else s.length>0&&(r.voice=this.options.pickVoice?this.options.pickVoice(s):ca(s));e.rate!==void 0&&(r.rate=e.rate),e.pitch!==void 0&&(r.pitch=e.pitch),r.onend=()=>n.onEnd?.(),r.onerror=a=>{let l=a.error;l==="canceled"||l==="interrupted"?n.onEnd?.():n.onError?.(new Error(l||"Speech synthesis failed"))},setTimeout(()=>{o.speak(r),n.onStart?.()},50)}pause(){t.isSupported()&&window.speechSynthesis.pause()}resume(){t.isSupported()&&window.speechSynthesis.resume()}stop(){t.isSupported()&&window.speechSynthesis.cancel()}};var Kr=class{constructor(e){this.resolveEngine=e;this.engine=null;this.activeId=null;this.state="idle";this.listeners=new Set;this.generation=0}get supportsPause(){return this.engine?.supportsPause??!0}stateFor(e){return this.activeId===e?this.state:"idle"}activeMessageId(){return this.activeId}onChange(e){return this.listeners.add(e),()=>this.listeners.delete(e)}toggle(e,n){if(this.activeId===e){if(this.state==="playing"){this.engine?.supportsPause?(this.engine.pause(),this.set(e,"paused")):this.stop();return}if(this.state==="paused"){this.engine?.resume(),this.set(e,"playing");return}if(this.state==="loading"){this.stop();return}}this.play(e,n)}async play(e,n){let o=++this.generation;this.engine?.stop(),this.set(e,"loading");try{if(!this.engine){let r=await this.resolveEngine();if(o!==this.generation)return;if(!r){this.set(null,"idle");return}this.engine=r}this.engine.speak(n,{onStart:()=>{o===this.generation&&this.set(e,"playing")},onEnd:()=>{o===this.generation&&this.set(null,"idle")},onError:()=>{o===this.generation&&this.set(null,"idle")}})}catch{o===this.generation&&this.set(null,"idle")}}stop(){this.generation++,this.engine?.stop(),this.set(null,"idle")}destroy(){this.stop(),this.engine?.destroy?.(),this.engine=null,this.listeners.clear()}set(e,n){this.activeId=n==="idle"?null:e,this.state=n;for(let o of this.listeners)o(this.activeId,this.state)}};function zi(t){if(!t)return"";let e=qg(t);return zd(e!==null?e:t)}function qg(t){let e=t.trim(),n=e.match(/^```(?:json)?\s*([\s\S]*?)\s*```$/i);if(n&&(e=n[1].trim()),!e.startsWith("{"))return null;try{let o=JSON.parse(e);if(o&&typeof o=="object"&&typeof o.text=="string")return o.text}catch{}return null}function zd(t){if(!t)return"";let e=t;return e=e.replace(/```[\s\S]*?```/g," "),e=e.replace(/~~~[\s\S]*?~~~/g," "),e=e.replace(/`([^`]+)`/g,"$1"),e=e.replace(/!\[([^\]]*)\]\([^)]*\)/g,"$1"),e=e.replace(/\[([^\]]+)\]\([^)]*\)/g,"$1"),e=e.replace(/\[([^\]]+)\]\[[^\]]*\]/g,"$1"),e=e.replace(/<\/?[a-zA-Z][^>]*>/g," "),e=e.replace(/^[ \t]*#{1,6}[ \t]+/gm,""),e=e.replace(/^[ \t]*>[ \t]?/gm,""),e=e.replace(/^[ \t]*[-*+][ \t]+/gm,""),e=e.replace(/^[ \t]*\d+\.[ \t]+/gm,""),e=e.replace(/^[ \t]*([-*_])([ \t]*\1){2,}[ \t]*$/gm," "),e=e.replace(/(\*\*|__)(.*?)\1/g,"$2"),e=e.replace(/(\*|_)(.*?)\1/g,"$2"),e=e.replace(/~~(.*?)~~/g,"$1"),e=e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,'"').replace(/'/g,"'").replace(/ /g," "),e=e.replace(/[ \t]+/g," "),e=e.replace(/[ \t]*\n[ \t]*/g,`
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtypelabs/persona",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.12.0",
|
|
4
4
|
"description": "Themeable, pluggable streaming agent widget for websites, in plain JS with support for voice input and reasoning / tool output.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
package/src/codegen.test.ts
CHANGED
|
@@ -23,6 +23,49 @@ describe("codegen subpath", () => {
|
|
|
23
23
|
expect(code).not.toContain("@latest");
|
|
24
24
|
});
|
|
25
25
|
|
|
26
|
+
describe("cdnBase option", () => {
|
|
27
|
+
const cdnBase = "https://cdn.runtype.com/persona/latest";
|
|
28
|
+
|
|
29
|
+
it("emits the custom base in every script format", () => {
|
|
30
|
+
expect(fromSubpath(config, "script-installer", { cdnBase })).toContain(
|
|
31
|
+
`src="${cdnBase}/install.global.js"`
|
|
32
|
+
);
|
|
33
|
+
const manual = fromSubpath(config, "script-manual", { cdnBase });
|
|
34
|
+
expect(manual).toContain(`href="${cdnBase}/widget.css"`);
|
|
35
|
+
expect(manual).toContain(`src="${cdnBase}/index.global.js"`);
|
|
36
|
+
expect(fromSubpath(config, "script-advanced", { cdnBase })).toContain(
|
|
37
|
+
`var CDN_BASE = '${cdnBase}';`
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("tolerates a trailing slash", () => {
|
|
42
|
+
const code = fromSubpath(config, "script-installer", { cdnBase: `${cdnBase}/` });
|
|
43
|
+
expect(code).toContain(`src="${cdnBase}/install.global.js"`);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it("percent-encodes characters that could break the emitted JS/HTML contexts", () => {
|
|
47
|
+
const hostile = "https://cdn.example.com/x'\"\\`/persona";
|
|
48
|
+
const encoded = "https://cdn.example.com/x%27%22%5C%60/persona";
|
|
49
|
+
// script-advanced emits into a single-quoted JS literal
|
|
50
|
+
expect(fromSubpath(config, "script-advanced", { cdnBase: hostile })).toContain(
|
|
51
|
+
`var CDN_BASE = '${encoded}';`
|
|
52
|
+
);
|
|
53
|
+
// script-installer / script-manual emit into double-quoted HTML attributes
|
|
54
|
+
expect(fromSubpath(config, "script-installer", { cdnBase: hostile })).toContain(
|
|
55
|
+
`src="${encoded}/install.global.js"`
|
|
56
|
+
);
|
|
57
|
+
expect(fromSubpath(config, "script-manual", { cdnBase: hostile })).toContain(
|
|
58
|
+
`href="${encoded}/widget.css"`
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("leaves no jsDelivr URL behind when a custom base is set", () => {
|
|
63
|
+
for (const format of ["script-installer", "script-manual", "script-advanced"] as const) {
|
|
64
|
+
expect(fromSubpath(config, format, { cdnBase })).not.toContain("jsdelivr");
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
26
69
|
describe("mount target option", () => {
|
|
27
70
|
it("defaults to body when no target is given", () => {
|
|
28
71
|
expect(fromSubpath(config, "react-component")).toContain("target: 'body'");
|
package/src/install.test.ts
CHANGED
|
@@ -343,6 +343,89 @@ describe("install.ts: deferral gate", () => {
|
|
|
343
343
|
});
|
|
344
344
|
});
|
|
345
345
|
|
|
346
|
+
describe("install.ts: CDN base derivation", () => {
|
|
347
|
+
// The installer captures document.currentScript.src synchronously at module
|
|
348
|
+
// evaluation; fake it with an own-property override (jsdom's getter lives on
|
|
349
|
+
// the prototype, so a configurable instance property shadows it cleanly).
|
|
350
|
+
function setCurrentScript(src: string) {
|
|
351
|
+
const script = document.createElement("script");
|
|
352
|
+
script.src = src;
|
|
353
|
+
Object.defineProperty(document, "currentScript", { value: script, configurable: true });
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
afterEach(() => {
|
|
357
|
+
delete (document as any).currentScript;
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
/**
|
|
361
|
+
* Run the deferred path with NO bundles provided so loadCSS/loadLauncher
|
|
362
|
+
* inject real (never-resolving in jsdom) elements whose URLs we can read.
|
|
363
|
+
*/
|
|
364
|
+
async function installedUrls(installerOptions: any) {
|
|
365
|
+
await install({ config: { apiUrl: "/api", launcher: { enabled: true } }, ...installerOptions });
|
|
366
|
+
await flush();
|
|
367
|
+
const css = document.head.querySelector("link[rel=\"stylesheet\"][data-persona]") as HTMLLinkElement | null;
|
|
368
|
+
const scripts = Array.from(document.head.querySelectorAll("script")).map((s) => s.src);
|
|
369
|
+
return { cssHref: css?.href ?? null, scripts };
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
it("derives asset URLs from the installer's own script directory (first-party CDN)", async () => {
|
|
373
|
+
setCurrentScript("https://cdn.runtype.com/persona/latest/install.global.js");
|
|
374
|
+
const { cssHref, scripts } = await installedUrls({});
|
|
375
|
+
expect(cssHref).toBe("https://cdn.runtype.com/persona/latest/widget.css");
|
|
376
|
+
expect(scripts).toContain("https://cdn.runtype.com/persona/latest/launcher.global.js");
|
|
377
|
+
});
|
|
378
|
+
|
|
379
|
+
it("keeps npm-CDN siblings on the installer's own pinned range (no @latest skew)", async () => {
|
|
380
|
+
setCurrentScript("https://cdn.jsdelivr.net/npm/@runtypelabs/persona@4/dist/install.global.js");
|
|
381
|
+
const { cssHref, scripts } = await installedUrls({});
|
|
382
|
+
expect(cssHref).toBe("https://cdn.jsdelivr.net/npm/@runtypelabs/persona@4/dist/widget.css");
|
|
383
|
+
expect(scripts).toContain("https://cdn.jsdelivr.net/npm/@runtypelabs/persona@4/dist/launcher.global.js");
|
|
384
|
+
});
|
|
385
|
+
|
|
386
|
+
it("the full bundle URL follows the installer directory on the eager path", async () => {
|
|
387
|
+
setCurrentScript("https://cdn.runtype.com/persona/latest/install.global.js");
|
|
388
|
+
markCssLoaded();
|
|
389
|
+
await install({ config: { apiUrl: "/api", launcher: { enabled: false } } });
|
|
390
|
+
await flush();
|
|
391
|
+
const scripts = Array.from(document.head.querySelectorAll("script")).map((s) => s.src);
|
|
392
|
+
expect(scripts).toContain("https://cdn.runtype.com/persona/latest/index.global.js");
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it("falls back to jsDelivr@latest when currentScript is unavailable", async () => {
|
|
396
|
+
// No setCurrentScript: module/inline contexts have no script src.
|
|
397
|
+
const { cssHref } = await installedUrls({});
|
|
398
|
+
expect(cssHref).toBe("https://cdn.jsdelivr.net/npm/@runtypelabs/persona@latest/dist/widget.css");
|
|
399
|
+
});
|
|
400
|
+
|
|
401
|
+
it("falls back to the npm CDN for a non-http(s) installer source", async () => {
|
|
402
|
+
setCurrentScript("data:text/javascript,void%200");
|
|
403
|
+
const { cssHref } = await installedUrls({});
|
|
404
|
+
expect(cssHref).toBe("https://cdn.jsdelivr.net/npm/@runtypelabs/persona@latest/dist/widget.css");
|
|
405
|
+
});
|
|
406
|
+
|
|
407
|
+
it("an explicit `version` opts back into npm-CDN URLs even when the src is derivable", async () => {
|
|
408
|
+
setCurrentScript("https://cdn.runtype.com/persona/latest/install.global.js");
|
|
409
|
+
const { cssHref } = await installedUrls({ version: "1.2.3" });
|
|
410
|
+
expect(cssHref).toBe("https://cdn.jsdelivr.net/npm/@runtypelabs/persona@1.2.3/dist/widget.css");
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it("an explicit `cdn` opts back into npm-CDN URLs even when the src is derivable", async () => {
|
|
414
|
+
setCurrentScript("https://cdn.runtype.com/persona/latest/install.global.js");
|
|
415
|
+
const { cssHref } = await installedUrls({ cdn: "unpkg" });
|
|
416
|
+
expect(cssHref).toBe("https://unpkg.com/@runtypelabs/persona@latest/dist/widget.css");
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
it("explicit cssUrl + jsUrl win over the derived installer base", async () => {
|
|
420
|
+
setCurrentScript("https://cdn.runtype.com/persona/latest/install.global.js");
|
|
421
|
+
const { cssHref } = await installedUrls({
|
|
422
|
+
cssUrl: "https://assets.example.com/persona/widget.css",
|
|
423
|
+
jsUrl: "https://assets.example.com/persona/index.global.js",
|
|
424
|
+
});
|
|
425
|
+
expect(cssHref).toBe("https://assets.example.com/persona/widget.css");
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
|
|
346
429
|
describe("install.ts: onError", () => {
|
|
347
430
|
it("fires onError with phase 'init' and dispatches persona:error when initialization throws", async () => {
|
|
348
431
|
markCssLoaded();
|
package/src/install.ts
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
export {};
|
|
8
8
|
|
|
9
9
|
interface SiteAgentInstallConfig {
|
|
10
|
+
// Setting `version` or `cdn` explicitly opts into npm-CDN asset URLs
|
|
11
|
+
// (jsDelivr/unpkg). When neither is set, assets load from the directory the
|
|
12
|
+
// installer script itself was served from — see getCdnBase().
|
|
10
13
|
version?: string;
|
|
11
14
|
cdn?: "unpkg" | "jsdelivr";
|
|
12
15
|
cssUrl?: string;
|
|
@@ -137,6 +140,10 @@ declare global {
|
|
|
137
140
|
// Get config from script attributes (must be called synchronously during script execution)
|
|
138
141
|
const scriptConfig = getConfigFromScript();
|
|
139
142
|
|
|
143
|
+
// The installer's own URL, captured now because document.currentScript is
|
|
144
|
+
// null once synchronous execution ends (and always inside modules).
|
|
145
|
+
const installerSrc = (document.currentScript as HTMLScriptElement | null)?.src || "";
|
|
146
|
+
|
|
140
147
|
// Merge script attributes with window config (script attributes take precedence)
|
|
141
148
|
const windowConfig: SiteAgentInstallConfig = window.siteAgentConfig || {};
|
|
142
149
|
const config: SiteAgentInstallConfig = { ...windowConfig, ...scriptConfig };
|
|
@@ -194,7 +201,28 @@ declare global {
|
|
|
194
201
|
const cdn = config.cdn || "jsdelivr";
|
|
195
202
|
const autoInit = config.autoInit !== false; // Default to true
|
|
196
203
|
|
|
197
|
-
//
|
|
204
|
+
// Directory the installer itself was served from. Every published layout
|
|
205
|
+
// (npm CDN dist/, first-party CDN, self-hosted copies) keeps the sibling
|
|
206
|
+
// assets next to install.global.js, so this base is valid wherever the
|
|
207
|
+
// installer loaded from — and always satisfies the same CSP/origin rules
|
|
208
|
+
// that let the installer through. Non-http(s) sources (inline, blob:) and
|
|
209
|
+
// module contexts (no currentScript) yield null.
|
|
210
|
+
const getInstallerBase = (): string | null => {
|
|
211
|
+
if (!installerSrc) return null;
|
|
212
|
+
try {
|
|
213
|
+
const url = new URL(installerSrc, document.baseURI);
|
|
214
|
+
if (url.protocol !== "http:" && url.protocol !== "https:") return null;
|
|
215
|
+
return url.origin + url.pathname.slice(0, url.pathname.lastIndexOf("/"));
|
|
216
|
+
} catch {
|
|
217
|
+
return null;
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// Determine CDN base URL. Precedence:
|
|
222
|
+
// 1. explicit cssUrl + jsUrl
|
|
223
|
+
// 2. explicit `cdn` / `version` → npm CDN construction
|
|
224
|
+
// 3. the installer's own directory (default)
|
|
225
|
+
// 4. npm CDN construction (currentScript unavailable)
|
|
198
226
|
const getCdnBase = () => {
|
|
199
227
|
// For a custom URL override, derive the sibling launcher URL when the
|
|
200
228
|
// override mirrors the dist layout (…/index.global.js → …/launcher.global.js)
|
|
@@ -209,8 +237,26 @@ declare global {
|
|
|
209
237
|
};
|
|
210
238
|
}
|
|
211
239
|
|
|
240
|
+
// Default: load assets from wherever the installer was served, so a page
|
|
241
|
+
// whose CSP allows only its own CDN (e.g. cdn.runtype.com) never has
|
|
242
|
+
// sibling requests fan out to a third-party host. An explicit `cdn` or
|
|
243
|
+
// `version` keeps the documented npm-CDN behavior.
|
|
244
|
+
if (!config.cdn && !config.version) {
|
|
245
|
+
const selfBase = getInstallerBase();
|
|
246
|
+
if (selfBase) {
|
|
247
|
+
return {
|
|
248
|
+
cssUrl: `${selfBase}/widget.css`,
|
|
249
|
+
jsUrl: `${selfBase}/index.global.js`,
|
|
250
|
+
launcherUrl: `${selfBase}/launcher.global.js` as string | null,
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
212
255
|
const packageName = "@runtypelabs/persona";
|
|
213
|
-
|
|
256
|
+
// jsDelivr namespaces npm packages under /npm/; unpkg serves them at the root.
|
|
257
|
+
const basePath = cdn === "unpkg"
|
|
258
|
+
? `/${packageName}@${version}/dist`
|
|
259
|
+
: `/npm/${packageName}@${version}/dist`;
|
|
214
260
|
const host = cdn === "unpkg" ? "https://unpkg.com" : "https://cdn.jsdelivr.net";
|
|
215
261
|
|
|
216
262
|
return {
|
|
@@ -151,8 +151,33 @@ export type CodeGeneratorOptions = {
|
|
|
151
151
|
* @default "body"
|
|
152
152
|
*/
|
|
153
153
|
target?: string;
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Base URL of the directory holding the widget assets (install.global.js,
|
|
157
|
+
* index.global.js, widget.css) for the script formats (script-installer,
|
|
158
|
+
* script-manual, script-advanced). Pass a first-party base such as
|
|
159
|
+
* "https://cdn.runtype.com/persona/latest" when the embedding page's CSP
|
|
160
|
+
* does not allow third-party CDNs. A trailing slash is tolerated.
|
|
161
|
+
* @default the jsDelivr dist directory pinned to this package version
|
|
162
|
+
*/
|
|
163
|
+
cdnBase?: string;
|
|
154
164
|
};
|
|
155
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Asset directory for script formats: explicit cdnBase or the version-pinned
|
|
168
|
+
* jsDelivr dist. The base is emitted into single-quoted JS literals AND
|
|
169
|
+
* double-quoted HTML attributes, so percent-encode the characters that could
|
|
170
|
+
* break out of either context. All of them are illegal unencoded in a URL
|
|
171
|
+
* (RFC 3986), so encoding never changes the meaning of a valid base URL.
|
|
172
|
+
*/
|
|
173
|
+
function resolveCdnBase(options?: CodeGeneratorOptions): string {
|
|
174
|
+
const base = options?.cdnBase
|
|
175
|
+
?.trim()
|
|
176
|
+
.replace(/\/+$/, "")
|
|
177
|
+
.replace(/[\\'"<>`]/g, (ch) => `%${ch.charCodeAt(0).toString(16).toUpperCase().padStart(2, "0")}`);
|
|
178
|
+
return base || `https://cdn.jsdelivr.net/npm/@runtypelabs/persona@${VERSION}/dist`;
|
|
179
|
+
}
|
|
180
|
+
|
|
156
181
|
// Internal type for normalized hooks (always strings)
|
|
157
182
|
type NormalizedHooks = {
|
|
158
183
|
[K in keyof CodeGeneratorHooks]: string | undefined;
|
|
@@ -1402,7 +1427,7 @@ function generateScriptInstallerCode(config: any, options?: CodeGeneratorOptions
|
|
|
1402
1427
|
// Escape single quotes in JSON for HTML attribute
|
|
1403
1428
|
const configJson = JSON.stringify(payload, null, 0).replace(/'/g, "'");
|
|
1404
1429
|
|
|
1405
|
-
return `<script src="
|
|
1430
|
+
return `<script src="${resolveCdnBase(options)}/install.global.js" data-config='${configJson}'></script>`;
|
|
1406
1431
|
}
|
|
1407
1432
|
|
|
1408
1433
|
function generateScriptManualCode(config: any, options?: CodeGeneratorOptions): string {
|
|
@@ -1410,12 +1435,13 @@ function generateScriptManualCode(config: any, options?: CodeGeneratorOptions):
|
|
|
1410
1435
|
const parserType = getParserTypeFromConfig(config as AgentWidgetConfig);
|
|
1411
1436
|
const shouldEmitParserType = parserType !== "plain";
|
|
1412
1437
|
|
|
1438
|
+
const cdnBase = resolveCdnBase(options);
|
|
1413
1439
|
const lines: string[] = [
|
|
1414
1440
|
"<!-- Load CSS -->",
|
|
1415
|
-
`<link rel="stylesheet" href="
|
|
1441
|
+
`<link rel="stylesheet" href="${cdnBase}/widget.css" />`,
|
|
1416
1442
|
"",
|
|
1417
1443
|
"<!-- Load JavaScript -->",
|
|
1418
|
-
`<script src="
|
|
1444
|
+
`<script src="${cdnBase}/index.global.js"></script>`,
|
|
1419
1445
|
"",
|
|
1420
1446
|
"<!-- Initialize widget -->",
|
|
1421
1447
|
"<script>",
|
|
@@ -1565,7 +1591,7 @@ function generateScriptAdvancedCode(config: any, options?: CodeGeneratorOptions)
|
|
|
1565
1591
|
` var CONFIG = ${configJson.split('\n').map((line, i) => i === 0 ? line : ' ' + line).join('\n')};`,
|
|
1566
1592
|
"",
|
|
1567
1593
|
" // Constants",
|
|
1568
|
-
` var CDN_BASE = '
|
|
1594
|
+
` var CDN_BASE = '${resolveCdnBase(options)}';`,
|
|
1569
1595
|
" var STORAGE_KEY = 'chat-widget-state';",
|
|
1570
1596
|
" var PROCESSED_ACTIONS_KEY = 'chat-widget-processed-actions';",
|
|
1571
1597
|
"",
|