@runtypelabs/persona 4.21.0 → 4.22.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/{approval-ui-RNNBR5R3.js → approval-ui-K7R5Q5OC.js} +1 -1
- package/dist/approval-ui.cjs +2 -2
- package/dist/approval-ui.d.cts +73 -2
- package/dist/approval-ui.d.ts +73 -2
- package/dist/approval-ui.js +2 -2
- package/dist/artifacts-ui-F4N6VMKF.js +7 -0
- package/dist/artifacts-ui.cjs +1 -1
- package/dist/artifacts-ui.d.cts +73 -2
- package/dist/artifacts-ui.d.ts +73 -2
- package/dist/artifacts-ui.js +1 -1
- package/dist/chunk-NQLDCJAP.js +4 -0
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.js +1 -1
- package/dist/context-mentions.d.cts +73 -2
- package/dist/context-mentions.d.ts +73 -2
- package/dist/event-stream-view-FKWDY3UB.js +1 -0
- package/dist/event-stream-view.cjs +1 -1
- package/dist/event-stream-view.d.cts +73 -2
- package/dist/event-stream-view.d.ts +73 -2
- package/dist/event-stream-view.js +1 -1
- package/dist/forms-ui.d.cts +73 -2
- package/dist/forms-ui.d.ts +73 -2
- package/dist/index.cjs +66 -66
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +136 -5
- package/dist/index.d.ts +136 -5
- package/dist/index.global.js +50 -50
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +67 -67
- package/dist/index.js.map +1 -1
- package/dist/launcher.global.js +2 -2
- package/dist/launcher.global.js.map +1 -1
- package/dist/session-reconnect.d.cts +73 -2
- package/dist/session-reconnect.d.ts +73 -2
- package/dist/smart-dom-reader.d.cts +73 -2
- package/dist/smart-dom-reader.d.ts +73 -2
- package/dist/theme-editor-preview.cjs +65 -65
- package/dist/theme-editor-preview.d.cts +73 -2
- package/dist/theme-editor-preview.d.ts +73 -2
- package/dist/theme-editor-preview.js +49 -49
- package/dist/theme-editor.cjs +4 -4
- package/dist/theme-editor.d.cts +73 -2
- package/dist/theme-editor.d.ts +73 -2
- package/dist/theme-editor.js +2 -2
- package/dist/theme-reference.cjs +1 -1
- package/dist/theme-reference.d.cts +65 -1
- package/dist/theme-reference.d.ts +65 -1
- package/dist/theme-reference.js +1 -1
- package/dist/webmcp-polyfill.js +1 -4
- package/dist/webmcp-runtime-JI7T4QYF.js +6 -0
- package/dist/webmcp-runtime.cjs +2 -2
- package/dist/webmcp-runtime.d.cts +34 -2
- package/dist/webmcp-runtime.d.ts +34 -2
- package/dist/webmcp-runtime.js +2 -2
- package/package.json +2 -2
- package/src/client-visitor-history.test.ts +131 -0
- package/src/components/artifact-preview.ts +5 -0
- package/src/components/event-stream-badge-theming.test.ts +159 -0
- package/src/components/event-stream-view.ts +50 -20
- package/src/generated/runtype-openapi-contract.ts +8 -0
- package/src/index-core.ts +2 -0
- package/src/runtime/init.registry.test.ts +56 -0
- package/src/runtime/init.ts +17 -0
- package/src/types/theme.ts +41 -1
- package/src/types.ts +38 -1
- package/src/ui.reasoning-display.test.ts +136 -2
- package/src/ui.ts +69 -21
- package/src/utils/__snapshots__/tokens-parity.test.ts.snap +1740 -0
- package/src/utils/formatting.ts +22 -0
- package/src/utils/theme.ts +16 -0
- package/src/utils/tokens.ts +59 -0
- package/src/webmcp-bridge.test.ts +132 -23
- package/src/webmcp-bridge.ts +26 -2
- package/src/webmcp-runtime-entry.ts +71 -11
- package/dist/artifacts-ui-J6AKUGTS.js +0 -7
- package/dist/chunk-HBE7LFNT.js +0 -4
- package/dist/event-stream-view-73NWKWVQ.js +0 -1
- package/dist/webmcp-runtime-P3CHZRHF.js +0 -6
package/dist/webmcp-polyfill.js
CHANGED
|
@@ -1,4 +1 @@
|
|
|
1
|
-
var Ge=Object.defineProperty;var Ye=(e,t,r)=>t in e?Ge(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var I=(e,t,r)=>Ye(e,typeof t!="symbol"?t+"":t,r);function A(e,t){let r=typeof e;if(r!==typeof t)return!1;if(Array.isArray(e)){if(!Array.isArray(t))return!1;let n=e.length;if(n!==t.length)return!1;for(let i=0;i<n;i++)if(!A(e[i],t[i]))return!1;return!0}if(r==="object"){if(!e||!t)return e===t;let n=Object.keys(e),i=Object.keys(t);if(n.length!==i.length)return!1;for(let o of n)if(!A(e[o],t[o]))return!1;return!0}return e===t}function T(e){return encodeURI(Qe(e))}function Qe(e){return e.replace(/~/g,"~0").replace(/\//g,"~1")}var Ze={prefixItems:!0,items:!0,allOf:!0,anyOf:!0,oneOf:!0},Xe={$defs:!0,definitions:!0,properties:!0,patternProperties:!0,dependentSchemas:!0},Le={id:!0,$id:!0,$ref:!0,$schema:!0,$anchor:!0,$vocabulary:!0,$comment:!0,default:!0,enum:!0,const:!0,required:!0,type:!0,maximum:!0,minimum:!0,exclusiveMaximum:!0,exclusiveMinimum:!0,multipleOf:!0,maxLength:!0,minLength:!0,pattern:!0,format:!0,maxItems:!0,minItems:!0,uniqueItems:!0,maxProperties:!0,minProperties:!0},et=typeof self<"u"&&self.location&&self.location.origin!=="null"?new URL(self.location.origin+self.location.pathname+location.search):new URL("https://github.com/cfworker");function k(e,t=Object.create(null),r=et,n=""){if(e&&typeof e=="object"&&!Array.isArray(e)){let d=e.$id||e.id;if(d){let o=new URL(d,r.href);o.hash.length>1?t[o.href]=e:(o.hash="",n===""?r=o:k(e,t,r))}}else if(e!==!0&&e!==!1)return t;let i=r.href+(n?"#"+n:"");if(t[i]!==void 0)throw new Error(`Duplicate schema URI "${i}".`);if(t[i]=e,e===!0||e===!1)return t;if(e.__absolute_uri__===void 0&&Object.defineProperty(e,"__absolute_uri__",{enumerable:!1,value:i}),e.$ref&&e.__absolute_ref__===void 0){let d=new URL(e.$ref,r.href);d.hash=d.hash,Object.defineProperty(e,"__absolute_ref__",{enumerable:!1,value:d.href})}if(e.$recursiveRef&&e.__absolute_recursive_ref__===void 0){let d=new URL(e.$recursiveRef,r.href);d.hash=d.hash,Object.defineProperty(e,"__absolute_recursive_ref__",{enumerable:!1,value:d.href})}if(e.$anchor){let d=new URL("#"+e.$anchor,r.href);t[d.href]=e}for(let d in e){if(Le[d])continue;let o=`${n}/${T(d)}`,s=e[d];if(Array.isArray(s)){if(Ze[d]){let h=s.length;for(let b=0;b<h;b++)k(s[b],t,r,`${o}/${b}`)}}else if(Xe[d])for(let h in s)k(s[h],t,r,`${o}/${T(h)}`);else k(s,t,r,o)}return t}var tt=/^(\d\d\d\d)-(\d\d)-(\d\d)$/,rt=[0,31,28,31,30,31,30,31,31,30,31,30,31],ot=/^(\d\d):(\d\d):(\d\d)(\.\d+)?(z|[+-]\d\d(?::?\d\d)?)?$/i,nt=/^(?=.{1,253}\.?$)[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?(?:\.[a-z0-9](?:[-0-9a-z]{0,61}[0-9a-z])?)*\.?$/i,it=/^(?:[a-z][a-z0-9+\-.]*:)?(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'"()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'"()*+,;=:@]|%[0-9a-f]{2})*)*)?(?:\?(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'"()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i,st=/^(?:(?:[^\x00-\x20"'<>%\\^`{|}]|%[0-9a-f]{2})|\{[+#./;?&=,!@|]?(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?(?:,(?:[a-z0-9_]|%[0-9a-f]{2})+(?::[1-9][0-9]{0,3}|\*)?)*\})*$/i,dt=/^(?:(?:https?|ftp):\/\/)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d{1,3}){3})(?!127(?:\.\d{1,3}){3})(?!169\.254(?:\.\d{1,3}){2})(?!192\.168(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)(?:\.(?:[a-z\u{00a1}-\u{ffff}0-9]+-?)*[a-z\u{00a1}-\u{ffff}0-9]+)*(?:\.(?:[a-z\u{00a1}-\u{ffff}]{2,})))(?::\d{2,5})?(?:\/[^\s]*)?$/iu,at=/^(?:urn:uuid:)?[0-9a-f]{8}-(?:[0-9a-f]{4}-){3}[0-9a-f]{12}$/i,lt=/^(?:\/(?:[^~/]|~0|~1)*)*$/,ft=/^#(?:\/(?:[a-z0-9_\-.!$&'()*+,;:=@]|%[0-9a-f]{2}|~0|~1)*)*$/i,ut=/^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/,ct=e=>{if(e[0]==='"')return!1;let[t,r,...n]=e.split("@");return!t||!r||n.length!==0||t.length>64||r.length>253||t[0]==="."||t.endsWith(".")||t.includes("..")||!/^[a-z0-9.-]+$/i.test(r)||!/^[a-z0-9.!#$%&'*+/=?^_`{|}~-]+$/i.test(t)?!1:r.split(".").every(i=>/^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$/i.test(i))},mt=/^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$/,pt=/^((([0-9a-f]{1,4}:){7}([0-9a-f]{1,4}|:))|(([0-9a-f]{1,4}:){6}(:[0-9a-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){5}(((:[0-9a-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9a-f]{1,4}:){4}(((:[0-9a-f]{1,4}){1,3})|((:[0-9a-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){3}(((:[0-9a-f]{1,4}){1,4})|((:[0-9a-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){2}(((:[0-9a-f]{1,4}){1,5})|((:[0-9a-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9a-f]{1,4}:){1}(((:[0-9a-f]{1,4}){1,6})|((:[0-9a-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9a-f]{1,4}){1,7})|((:[0-9a-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))$/i,yt=e=>e.length>1&&e.length<80&&(/^P\d+([.,]\d+)?W$/.test(e)||/^P[\dYMDTHS]*(\d[.,]\d+)?[YMDHS]$/.test(e)&&/^P([.,\d]+Y)?([.,\d]+M)?([.,\d]+D)?(T([.,\d]+H)?([.,\d]+M)?([.,\d]+S)?)?$/.test(e));function _(e){return e.test.bind(e)}var ce={date:Me,time:Ce.bind(void 0,!1),"date-time":gt,duration:yt,uri:bt,"uri-reference":_(it),"uri-template":_(st),url:_(dt),email:ct,hostname:_(nt),ipv4:_(mt),ipv6:_(pt),regex:St,uuid:_(at),"json-pointer":_(lt),"json-pointer-uri-fragment":_(ft),"relative-json-pointer":_(ut)};function ht(e){return e%4===0&&(e%100!==0||e%400===0)}function Me(e){let t=e.match(tt);if(!t)return!1;let r=+t[1],n=+t[2],i=+t[3];return n>=1&&n<=12&&i>=1&&i<=(n==2&&ht(r)?29:rt[n])}function Ce(e,t){let r=t.match(ot);if(!r)return!1;let n=+r[1],i=+r[2],d=+r[3],o=!!r[5];return(n<=23&&i<=59&&d<=59||n==23&&i==59&&d==60)&&(!e||o)}var $t=/t|\s/i;function gt(e){let t=e.split($t);return t.length==2&&Me(t[0])&&Ce(!0,t[1])}var wt=/\/|:/,xt=/^(?:[a-z][a-z0-9+\-.]*:)(?:\/?\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:]|%[0-9a-f]{2})*@)?(?:\[(?:(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:){0,1}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)|[Vv][0-9a-f]+\.[a-z0-9\-._~!$&'()*+,;=:]+)\]|(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)|(?:[a-z0-9\-._~!$&'()*+,;=]|%[0-9a-f]{2})*)(?::\d*)?(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*|\/(?:(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)?|(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})+(?:\/(?:[a-z0-9\-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*)*)(?:\?(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?(?:#(?:[a-z0-9\-._~!$&'()*+,;=:@/?]|%[0-9a-f]{2})*)?$/i;function bt(e){return wt.test(e)&&xt.test(e)}var vt=/[^\\]\\Z/;function St(e){if(vt.test(e))return!1;try{return new RegExp(e,"u"),!0}catch{return!1}}var Ne;(function(e){e[e.Flag=1]="Flag",e[e.Basic=2]="Basic",e[e.Detailed=4]="Detailed"})(Ne||(Ne={}));function Ae(e){let t=0,r=e.length,n=0,i;for(;n<r;)t++,i=e.charCodeAt(n++),i>=55296&&i<=56319&&n<r&&(i=e.charCodeAt(n),(i&64512)==56320&&n++);return t}function w(e,t,r="2019-09",n=k(t),i=!0,d=null,o="#",s="#",h=Object.create(null)){if(t===!0)return{valid:!0,errors:[]};if(t===!1)return{valid:!1,errors:[{instanceLocation:o,keyword:"false",keywordLocation:o,error:"False boolean schema."}]};let b=typeof e,$;switch(b){case"boolean":case"number":case"string":$=b;break;case"object":e===null?$="null":Array.isArray(e)?$="array":$="object";break;default:throw new Error(`Instances of "${b}" type are not supported.`)}let{$ref:P,$recursiveRef:W,$recursiveAnchor:M,type:S,const:z,enum:D,required:he,not:$e,anyOf:ee,allOf:te,oneOf:ge,if:we,then:xe,else:be,format:q,properties:re,patternProperties:oe,additionalProperties:ve,unevaluatedProperties:Se,minProperties:ne,maxProperties:ie,propertyNames:Ie,dependentRequired:se,dependentSchemas:de,dependencies:ae,prefixItems:le,items:R,additionalItems:Te,unevaluatedItems:_e,contains:Oe,minContains:E,maxContains:U,minItems:fe,maxItems:ue,uniqueItems:Be,minimum:C,maximum:N,exclusiveMinimum:J,exclusiveMaximum:V,multipleOf:H,minLength:F,maxLength:B,pattern:Ee,__absolute_ref__:K,__absolute_recursive_ref__:Ke}=t,l=[];if(M===!0&&d===null&&(d=t),W==="#"){let c=d===null?n[Ke]:d,u=`${s}/$recursiveRef`,y=w(e,d===null?t:d,r,n,i,c,o,u,h);y.valid||l.push({instanceLocation:o,keyword:"$recursiveRef",keywordLocation:u,error:"A subschema had errors."},...y.errors)}if(P!==void 0){let u=n[K||P];if(u===void 0){let a=`Unresolved $ref "${P}".`;throw K&&K!==P&&(a+=` Absolute URI "${K}".`),a+=`
|
|
2
|
-
Known schemas:
|
|
3
|
-
- ${Object.keys(n).join(`
|
|
4
|
-
- `)}`,new Error(a)}let y=`${s}/$ref`,f=w(e,u,r,n,i,d,o,y,h);if(f.valid||l.push({instanceLocation:o,keyword:"$ref",keywordLocation:y,error:"A subschema had errors."},...f.errors),r==="4"||r==="7")return{valid:l.length===0,errors:l}}if(Array.isArray(S)){let c=S.length,u=!1;for(let y=0;y<c;y++)if($===S[y]||S[y]==="integer"&&$==="number"&&e%1===0&&e===e){u=!0;break}u||l.push({instanceLocation:o,keyword:"type",keywordLocation:`${s}/type`,error:`Instance type "${$}" is invalid. Expected "${S.join('", "')}".`})}else S==="integer"?($!=="number"||e%1||e!==e)&&l.push({instanceLocation:o,keyword:"type",keywordLocation:`${s}/type`,error:`Instance type "${$}" is invalid. Expected "${S}".`}):S!==void 0&&$!==S&&l.push({instanceLocation:o,keyword:"type",keywordLocation:`${s}/type`,error:`Instance type "${$}" is invalid. Expected "${S}".`});if(z!==void 0&&($==="object"||$==="array"?A(e,z)||l.push({instanceLocation:o,keyword:"const",keywordLocation:`${s}/const`,error:`Instance does not match ${JSON.stringify(z)}.`}):e!==z&&l.push({instanceLocation:o,keyword:"const",keywordLocation:`${s}/const`,error:`Instance does not match ${JSON.stringify(z)}.`})),D!==void 0&&($==="object"||$==="array"?D.some(c=>A(e,c))||l.push({instanceLocation:o,keyword:"enum",keywordLocation:`${s}/enum`,error:`Instance does not match any of ${JSON.stringify(D)}.`}):D.some(c=>e===c)||l.push({instanceLocation:o,keyword:"enum",keywordLocation:`${s}/enum`,error:`Instance does not match any of ${JSON.stringify(D)}.`})),$e!==void 0){let c=`${s}/not`;w(e,$e,r,n,i,d,o,c).valid&&l.push({instanceLocation:o,keyword:"not",keywordLocation:c,error:'Instance matched "not" schema.'})}let G=[];if(ee!==void 0){let c=`${s}/anyOf`,u=l.length,y=!1;for(let f=0;f<ee.length;f++){let a=ee[f],p=Object.create(h),m=w(e,a,r,n,i,M===!0?d:null,o,`${c}/${f}`,p);l.push(...m.errors),y=y||m.valid,m.valid&&G.push(p)}y?l.length=u:l.splice(u,0,{instanceLocation:o,keyword:"anyOf",keywordLocation:c,error:"Instance does not match any subschemas."})}if(te!==void 0){let c=`${s}/allOf`,u=l.length,y=!0;for(let f=0;f<te.length;f++){let a=te[f],p=Object.create(h),m=w(e,a,r,n,i,M===!0?d:null,o,`${c}/${f}`,p);l.push(...m.errors),y=y&&m.valid,m.valid&&G.push(p)}y?l.length=u:l.splice(u,0,{instanceLocation:o,keyword:"allOf",keywordLocation:c,error:"Instance does not match every subschema."})}if(ge!==void 0){let c=`${s}/oneOf`,u=l.length,y=ge.filter((f,a)=>{let p=Object.create(h),m=w(e,f,r,n,i,M===!0?d:null,o,`${c}/${a}`,p);return l.push(...m.errors),m.valid&&G.push(p),m.valid}).length;y===1?l.length=u:l.splice(u,0,{instanceLocation:o,keyword:"oneOf",keywordLocation:c,error:`Instance does not match exactly one subschema (${y} matches).`})}if(($==="object"||$==="array")&&Object.assign(h,...G),we!==void 0){let c=`${s}/if`;if(w(e,we,r,n,i,d,o,c,h).valid){if(xe!==void 0){let y=w(e,xe,r,n,i,d,o,`${s}/then`,h);y.valid||l.push({instanceLocation:o,keyword:"if",keywordLocation:c,error:'Instance does not match "then" schema.'},...y.errors)}}else if(be!==void 0){let y=w(e,be,r,n,i,d,o,`${s}/else`,h);y.valid||l.push({instanceLocation:o,keyword:"if",keywordLocation:c,error:'Instance does not match "else" schema.'},...y.errors)}}if($==="object"){if(he!==void 0)for(let f of he)f in e||l.push({instanceLocation:o,keyword:"required",keywordLocation:`${s}/required`,error:`Instance does not have required property "${f}".`});let c=Object.keys(e);if(ne!==void 0&&c.length<ne&&l.push({instanceLocation:o,keyword:"minProperties",keywordLocation:`${s}/minProperties`,error:`Instance does not have at least ${ne} properties.`}),ie!==void 0&&c.length>ie&&l.push({instanceLocation:o,keyword:"maxProperties",keywordLocation:`${s}/maxProperties`,error:`Instance does not have at least ${ie} properties.`}),Ie!==void 0){let f=`${s}/propertyNames`;for(let a in e){let p=`${o}/${T(a)}`,m=w(a,Ie,r,n,i,d,p,f);m.valid||l.push({instanceLocation:o,keyword:"propertyNames",keywordLocation:f,error:`Property name "${a}" does not match schema.`},...m.errors)}}if(se!==void 0){let f=`${s}/dependantRequired`;for(let a in se)if(a in e){let p=se[a];for(let m of p)m in e||l.push({instanceLocation:o,keyword:"dependentRequired",keywordLocation:f,error:`Instance has "${a}" but does not have "${m}".`})}}if(de!==void 0)for(let f in de){let a=`${s}/dependentSchemas`;if(f in e){let p=w(e,de[f],r,n,i,d,o,`${a}/${T(f)}`,h);p.valid||l.push({instanceLocation:o,keyword:"dependentSchemas",keywordLocation:a,error:`Instance has "${f}" but does not match dependant schema.`},...p.errors)}}if(ae!==void 0){let f=`${s}/dependencies`;for(let a in ae)if(a in e){let p=ae[a];if(Array.isArray(p))for(let m of p)m in e||l.push({instanceLocation:o,keyword:"dependencies",keywordLocation:f,error:`Instance has "${a}" but does not have "${m}".`});else{let m=w(e,p,r,n,i,d,o,`${f}/${T(a)}`);m.valid||l.push({instanceLocation:o,keyword:"dependencies",keywordLocation:f,error:`Instance has "${a}" but does not match dependant schema.`},...m.errors)}}}let u=Object.create(null),y=!1;if(re!==void 0){let f=`${s}/properties`;for(let a in re){if(!(a in e))continue;let p=`${o}/${T(a)}`,m=w(e[a],re[a],r,n,i,d,p,`${f}/${T(a)}`);if(m.valid)h[a]=u[a]=!0;else if(y=i,l.push({instanceLocation:o,keyword:"properties",keywordLocation:f,error:`Property "${a}" does not match schema.`},...m.errors),y)break}}if(!y&&oe!==void 0){let f=`${s}/patternProperties`;for(let a in oe){let p=new RegExp(a,"u"),m=oe[a];for(let v in e){if(!p.test(v))continue;let ke=`${o}/${T(v)}`,Pe=w(e[v],m,r,n,i,d,ke,`${f}/${T(a)}`);Pe.valid?h[v]=u[v]=!0:(y=i,l.push({instanceLocation:o,keyword:"patternProperties",keywordLocation:f,error:`Property "${v}" matches pattern "${a}" but does not match associated schema.`},...Pe.errors))}}}if(!y&&ve!==void 0){let f=`${s}/additionalProperties`;for(let a in e){if(u[a])continue;let p=`${o}/${T(a)}`,m=w(e[a],ve,r,n,i,d,p,f);m.valid?h[a]=!0:(y=i,l.push({instanceLocation:o,keyword:"additionalProperties",keywordLocation:f,error:`Property "${a}" does not match additional properties schema.`},...m.errors))}}else if(!y&&Se!==void 0){let f=`${s}/unevaluatedProperties`;for(let a in e)if(!h[a]){let p=`${o}/${T(a)}`,m=w(e[a],Se,r,n,i,d,p,f);m.valid?h[a]=!0:l.push({instanceLocation:o,keyword:"unevaluatedProperties",keywordLocation:f,error:`Property "${a}" does not match unevaluated properties schema.`},...m.errors)}}}else if($==="array"){ue!==void 0&&e.length>ue&&l.push({instanceLocation:o,keyword:"maxItems",keywordLocation:`${s}/maxItems`,error:`Array has too many items (${e.length} > ${ue}).`}),fe!==void 0&&e.length<fe&&l.push({instanceLocation:o,keyword:"minItems",keywordLocation:`${s}/minItems`,error:`Array has too few items (${e.length} < ${fe}).`});let c=e.length,u=0,y=!1;if(le!==void 0){let f=`${s}/prefixItems`,a=Math.min(le.length,c);for(;u<a;u++){let p=w(e[u],le[u],r,n,i,d,`${o}/${u}`,`${f}/${u}`);if(h[u]=!0,!p.valid&&(y=i,l.push({instanceLocation:o,keyword:"prefixItems",keywordLocation:f,error:"Items did not match schema."},...p.errors),y))break}}if(R!==void 0){let f=`${s}/items`;if(Array.isArray(R)){let a=Math.min(R.length,c);for(;u<a;u++){let p=w(e[u],R[u],r,n,i,d,`${o}/${u}`,`${f}/${u}`);if(h[u]=!0,!p.valid&&(y=i,l.push({instanceLocation:o,keyword:"items",keywordLocation:f,error:"Items did not match schema."},...p.errors),y))break}}else for(;u<c;u++){let a=w(e[u],R,r,n,i,d,`${o}/${u}`,f);if(h[u]=!0,!a.valid&&(y=i,l.push({instanceLocation:o,keyword:"items",keywordLocation:f,error:"Items did not match schema."},...a.errors),y))break}if(!y&&Te!==void 0){let a=`${s}/additionalItems`;for(;u<c;u++){let p=w(e[u],Te,r,n,i,d,`${o}/${u}`,a);h[u]=!0,p.valid||(y=i,l.push({instanceLocation:o,keyword:"additionalItems",keywordLocation:a,error:"Items did not match additional items schema."},...p.errors))}}}if(Oe!==void 0)if(c===0&&E===void 0)l.push({instanceLocation:o,keyword:"contains",keywordLocation:`${s}/contains`,error:"Array is empty. It must contain at least one item matching the schema."});else if(E!==void 0&&c<E)l.push({instanceLocation:o,keyword:"minContains",keywordLocation:`${s}/minContains`,error:`Array has less items (${c}) than minContains (${E}).`});else{let f=`${s}/contains`,a=l.length,p=0;for(let m=0;m<c;m++){let v=w(e[m],Oe,r,n,i,d,`${o}/${m}`,f);v.valid?(h[m]=!0,p++):l.push(...v.errors)}p>=(E||0)&&(l.length=a),E===void 0&&U===void 0&&p===0?l.splice(a,0,{instanceLocation:o,keyword:"contains",keywordLocation:f,error:"Array does not contain item matching schema."}):E!==void 0&&p<E?l.push({instanceLocation:o,keyword:"minContains",keywordLocation:`${s}/minContains`,error:`Array must contain at least ${E} items matching schema. Only ${p} items were found.`}):U!==void 0&&p>U&&l.push({instanceLocation:o,keyword:"maxContains",keywordLocation:`${s}/maxContains`,error:`Array may contain at most ${U} items matching schema. ${p} items were found.`})}if(!y&&_e!==void 0){let f=`${s}/unevaluatedItems`;for(u;u<c;u++){if(h[u])continue;let a=w(e[u],_e,r,n,i,d,`${o}/${u}`,f);h[u]=!0,a.valid||l.push({instanceLocation:o,keyword:"unevaluatedItems",keywordLocation:f,error:"Items did not match unevaluated items schema."},...a.errors)}}if(Be)for(let f=0;f<c;f++){let a=e[f],p=typeof a=="object"&&a!==null;for(let m=0;m<c;m++){if(f===m)continue;let v=e[m];(a===v||p&&(typeof v=="object"&&v!==null)&&A(a,v))&&(l.push({instanceLocation:o,keyword:"uniqueItems",keywordLocation:`${s}/uniqueItems`,error:`Duplicate items at indexes ${f} and ${m}.`}),f=Number.MAX_SAFE_INTEGER,m=Number.MAX_SAFE_INTEGER)}}}else if($==="number"){if(r==="4"?(C!==void 0&&(J===!0&&e<=C||e<C)&&l.push({instanceLocation:o,keyword:"minimum",keywordLocation:`${s}/minimum`,error:`${e} is less than ${J?"or equal to ":""} ${C}.`}),N!==void 0&&(V===!0&&e>=N||e>N)&&l.push({instanceLocation:o,keyword:"maximum",keywordLocation:`${s}/maximum`,error:`${e} is greater than ${V?"or equal to ":""} ${N}.`})):(C!==void 0&&e<C&&l.push({instanceLocation:o,keyword:"minimum",keywordLocation:`${s}/minimum`,error:`${e} is less than ${C}.`}),N!==void 0&&e>N&&l.push({instanceLocation:o,keyword:"maximum",keywordLocation:`${s}/maximum`,error:`${e} is greater than ${N}.`}),J!==void 0&&e<=J&&l.push({instanceLocation:o,keyword:"exclusiveMinimum",keywordLocation:`${s}/exclusiveMinimum`,error:`${e} is less than ${J}.`}),V!==void 0&&e>=V&&l.push({instanceLocation:o,keyword:"exclusiveMaximum",keywordLocation:`${s}/exclusiveMaximum`,error:`${e} is greater than or equal to ${V}.`})),H!==void 0){let c=e%H;Math.abs(0-c)>=11920929e-14&&Math.abs(H-c)>=11920929e-14&&l.push({instanceLocation:o,keyword:"multipleOf",keywordLocation:`${s}/multipleOf`,error:`${e} is not a multiple of ${H}.`})}}else if($==="string"){let c=F===void 0&&B===void 0?0:Ae(e);F!==void 0&&c<F&&l.push({instanceLocation:o,keyword:"minLength",keywordLocation:`${s}/minLength`,error:`String is too short (${c} < ${F}).`}),B!==void 0&&c>B&&l.push({instanceLocation:o,keyword:"maxLength",keywordLocation:`${s}/maxLength`,error:`String is too long (${c} > ${B}).`}),Ee!==void 0&&!new RegExp(Ee,"u").test(e)&&l.push({instanceLocation:o,keyword:"pattern",keywordLocation:`${s}/pattern`,error:"String does not match pattern."}),q!==void 0&&ce[q]&&!ce[q](e)&&l.push({instanceLocation:o,keyword:"format",keywordLocation:`${s}/format`,error:`String does not match format "${q}".`})}return{valid:l.length===0,errors:l}}var Y=class{constructor(t,r="2019-09",n=!0){I(this,"schema");I(this,"draft");I(this,"shortCircuit");I(this,"lookup");this.schema=t,this.draft=r,this.shortCircuit=n,this.lookup=k(t)}validate(t){return w(t,this.schema,this.draft,this.lookup,this.shortCircuit)}addSchema(t,r){r&&(t={...t,$id:r}),k(t,this.lookup)}};var Q={type:"object",properties:{}},It=["draft-2020-12","draft-07"];function x(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Tt(e){if(!x(e))return!1;let t=Object.getPrototypeOf(e);return t===Object.prototype||t===null}function je(e,t=new WeakSet){if(e===null||typeof e=="string"||typeof e=="boolean")return!0;if(typeof e=="number")return Number.isFinite(e);if(typeof e!="object"||t.has(e))return!1;t.add(e);try{return(Array.isArray(e)?e:Tt(e)?Object.values(e):null)?.every(r=>je(r,t))??!1}catch{return!1}finally{t.delete(e)}}function ze(e){return je(e)?e:void 0}function De(e){if(!x(e))return null;let t=e["~standard"];return x(t)?t:null}function _t(e){let t=De(e);return!!(t&&t.version===1&&typeof t.validate=="function")}function Ot(e){let t=De(e);return!t||t.version!==1||!x(t.jsonSchema)?!1:typeof t.jsonSchema.input=="function"}function Z(e){return{"~standard":{version:1,vendor:"@mcp-b/webmcp-polyfill-json-schema",validate(t){if(!x(t))return{issues:[{message:"expected object arguments"}]};let r=me(t,e);return r?{issues:[r]}:{value:t}}}}}function Et(e){let t=[];for(let r of It)try{let n=e["~standard"].jsonSchema.input({target:r});return Je(n),n}catch(n){t.push({target:r,error:n})}throw console.warn("[WebMCPPolyfill] Standard JSON Schema conversion failed:",t),new Error("Failed to convert Standard JSON Schema inputSchema to a JSON Schema object")}function Re(e){if(e===void 0){let r=Q;return{inputSchema:r,standardValidator:Z(r)}}if(Ot(e)){let r=Et(e);return{inputSchema:r,standardValidator:Z(r)}}if(_t(e))return{inputSchema:Q,standardValidator:e};if(Je(e),Object.keys(e).length===0)return{inputSchema:Q,standardValidator:Z(Q)};let t=e.type===void 0?{type:"object",...e}:e;return{inputSchema:t,standardValidator:Z(t)}}function Je(e){if(!x(e))throw new Error("inputSchema must be a JSON Schema object");j(e,"$")}function j(e,t){let r=e.type;if(r!==void 0&&typeof r!="string"&&!(Array.isArray(r)&&r.every(s=>typeof s=="string"&&s.length>0)))throw new Error(`Invalid JSON Schema at ${t}: "type" must be a string or string[]`);let n=e.required;if(n!==void 0&&!(Array.isArray(n)&&n.every(s=>typeof s=="string")))throw new Error(`Invalid JSON Schema at ${t}: "required" must be an array of strings`);let i=e.properties;if(i!==void 0){if(!x(i))throw new Error(`Invalid JSON Schema at ${t}: "properties" must be an object`);for(let[s,h]of Object.entries(i)){if(!x(h))throw new Error(`Invalid JSON Schema at ${t}.properties.${s}: expected object schema`);j(h,`${t}.properties.${s}`)}}let d=e.items;if(d!==void 0)if(Array.isArray(d))for(let[s,h]of d.entries()){if(!x(h))throw new Error(`Invalid JSON Schema at ${t}.items[${s}]: expected object schema`);j(h,`${t}.items[${s}]`)}else if(x(d))j(d,`${t}.items`);else throw new Error(`Invalid JSON Schema at ${t}: "items" must be an object or object[]`);for(let s of["allOf","anyOf","oneOf"]){let h=e[s];if(h!==void 0){if(!Array.isArray(h))throw new Error(`Invalid JSON Schema at ${t}: "${s}" must be an array`);for(let[b,$]of h.entries()){if(!x($))throw new Error(`Invalid JSON Schema at ${t}.${s}[${b}]: expected object schema`);j($,`${t}.${s}[${b}]`)}}}let o=e.not;if(o!==void 0){if(!x(o))throw new Error(`Invalid JSON Schema at ${t}: "not" must be an object schema`);j(o,`${t}.not`)}try{JSON.stringify(e)}catch{throw new Error(`Invalid JSON Schema at ${t}: schema must be JSON-serializable`)}}function me(e,t){let r=new Y(t,"2020-12",!0).validate(e);if(r.valid)return null;let n=r.errors[r.errors.length-1];return n?{message:n.error}:{message:"Input validation failed"}}var Ve="Failed to parse input arguments",X="Tool was executed but the invocation failed. For example, the script function threw an error",ye="Tool was cancelled",kt=/^[A-Za-z0-9_\-.]{1,128}$/u,Pt="__isWebMCPPolyfill",qe=Symbol("standardValidator");function Mt(){return new DOMException("signal is aborted without reason","AbortError")}var g={installed:!1,previousNavigatorModelContextDescriptor:void 0,previousNavigatorModelContextTestingDescriptor:void 0,previousDocumentModelContextDescriptor:void 0,installedNavigatorModelContext:!1,installedNavigatorModelContextTesting:!1,installedDocumentModelContext:!1},Ct=class extends EventTarget{constructor(){super(...arguments);I(this,"tools",new Map);I(this,"testingShim",null);I(this,"_ontoolchange",null);I(this,"unregisterToolDeprecationWarned",!1);I(this,"toolsChangedQueued",!1)}get ontoolchange(){return this._ontoolchange}set ontoolchange(t){this._ontoolchange=t}registerTool(t,r){let n=r?.signal;if(n?.aborted)return Promise.reject(Mt());let i=zt(t,this.tools);return this.tools.set(i.name,i),this.notifyToolsChanged(),n&&n.addEventListener("abort",()=>{this.tools.delete(i.name)&&this.notifyToolsChanged()},{once:!0}),Promise.resolve()}unregisterTool(t){this.warnUnregisterToolDeprecationOnce();let r=jt(t);this.tools.delete(r)&&this.notifyToolsChanged()}getTools(){return Promise.resolve(this.getRegisteredToolInfos())}executeTool(t,r,n){return this.executeToolByName(t.name,r,n,!1)}getTestingShim(){return this.testingShim||(this.testingShim=new Nt(this)),this.testingShim}getToolInfos(){return[...this.tools.values()].map(t=>{let r;try{r=JSON.stringify(t.inputSchema??{type:"object"})}catch{r='{"type":"object"}'}return{name:t.name,description:t.description,inputSchema:r}})}getRegisteredToolInfos(){return this.getToolInfos().map(t=>{let r=this.tools.get(t.name);return{...t,title:r?.title??"",origin:globalThis.location?.origin??"",window:globalThis.window}})}async executeToolForTesting(t,r,n){return this.executeToolByName(t,r,n,!0)}async executeToolByName(t,r,n,i){if(n?.signal?.aborted)throw O(ye);let d=this.tools.get(t);if(!d)throw O(`Tool not found: ${t}`);let o=At(r),s=await Jt(o,d);if(s)throw O(s);let h=!0,b={requestUserInteraction:async $=>{if(!h)throw new Error(`ModelContextClient for tool "${t}" is no longer active after execute() resolved`);if(typeof $!="function")throw new TypeError("requestUserInteraction(callback) requires a function callback");return $()}};try{let $=d.execute(o,b),P=await Bt(Promise.resolve($),n?.signal),W=Ut(P),M=Vt(W,d);if(M)throw new Error(M);if(i)return Ft(W);let S=JSON.stringify(P);return S===void 0?null:S}catch($){throw O($ instanceof Error?`${X}: ${$.message}`:X)}finally{h=!1}}notifyToolsChanged(){this.toolsChangedQueued||(this.toolsChangedQueued=!0,queueMicrotask(()=>{this.toolsChangedQueued=!1;let t=new Event("toolchange");try{this._ontoolchange?.call(this,t)}catch(r){console.warn("[WebMCPPolyfill] navigator.modelContext.ontoolchange handler threw:",r)}this.dispatchEvent(t),this.testingShim?.dispatchToolChange()}))}warnUnregisterToolDeprecationOnce(){this.unregisterToolDeprecationWarned||(this.unregisterToolDeprecationWarned=!0,console.warn("[WebMCPPolyfill] navigator.modelContext.unregisterTool() is deprecated. The April 23, 2026 WebMCP draft removed it in favor of registerTool(tool, { signal }) \u2014 pass an AbortSignal and abort it to unregister."))}},Nt=class extends EventTarget{constructor(t){super();I(this,"context");I(this,"_ontoolchange",null);this.context=t}listTools(){return this.context.getToolInfos()}executeTool(t,r,n){return this.context.executeToolForTesting(t,r,n)}getCrossDocumentScriptToolResult(){return Promise.resolve("[]")}get ontoolchange(){return this._ontoolchange}set ontoolchange(t){this._ontoolchange=t}registerToolsChangedCallback(t){if(typeof t!="function")throw new TypeError("Failed to execute 'registerToolsChangedCallback' on 'ModelContextTesting': parameter 1 is not of type 'Function'.");this.addEventListener("toolchange",t)}dispatchToolChange(){let t=new Event("toolchange");try{this._ontoolchange?.call(this,t)}catch(r){console.warn("[WebMCPPolyfill] ontoolchange handler threw:",r)}this.dispatchEvent(t),this.dispatchEvent(new Event("toolschanged"))}};function O(e){try{return new DOMException(e,"UnknownError")}catch{let t=new Error(e);return t.name="UnknownError",t}}function pe(e){try{return new DOMException(e,"InvalidStateError")}catch{let t=new Error(e);return t.name="InvalidStateError",t}}function At(e){let t;try{t=JSON.parse(e)}catch{throw O(Ve)}if(!t||typeof t!="object"||Array.isArray(t))throw O(Ve);return t}function jt(e){if(typeof e=="string")return e;if(x(e)&&typeof e.name=="string")return e.name;throw new TypeError("Failed to execute 'unregisterTool' on 'ModelContext': parameter 1 must be a string or an object with a string name.")}function zt(e,t){if(!e||typeof e!="object")throw new TypeError("registerTool(tool) requires a tool object");if(typeof e.name!="string"||e.name.length===0)throw pe('Tool "name" must be a non-empty string');if(!kt.test(e.name)||Array.from(e.name).length>128)throw pe('Tool "name" must be 1\u2013128 characters and contain only ASCII alphanumeric, underscore, hyphen, or period');if(typeof e.description!="string"||e.description.length===0)throw pe('Tool "description" must be a non-empty string');if(typeof e.execute!="function")throw new TypeError('Tool "execute" must be a function');if(t.has(e.name))throw new Error(`Tool already registered: ${e.name}`);let r=Re(e.inputSchema),n=e.annotations,i=n?{...n,...n.readOnlyHint==="true"?{readOnlyHint:!0}:n.readOnlyHint==="false"?{readOnlyHint:!1}:{},...n.destructiveHint==="true"?{destructiveHint:!0}:n.destructiveHint==="false"?{destructiveHint:!1}:{},...n.idempotentHint==="true"?{idempotentHint:!0}:n.idempotentHint==="false"?{idempotentHint:!1}:{},...n.openWorldHint==="true"?{openWorldHint:!0}:n.openWorldHint==="false"?{openWorldHint:!1}:{}}:void 0;return{...e,...i?{annotations:i}:{},inputSchema:r.inputSchema,[qe]:r.standardValidator}}function Dt(e){if(!e||e.length===0)return null;let t=e.map(r=>x(r)&&"key"in r?r.key:r).map(r=>String(r)).filter(r=>r.length>0);return t.length===0?null:t.join(".")}async function Rt(e,t){let r;try{r=await Promise.resolve(t["~standard"].validate(e))}catch(d){let o=d instanceof Error?`: ${d.message}`:"";return console.error("[WebMCPPolyfill] Standard Schema validation threw unexpectedly:",d),`Input validation error: schema validation failed${o}`}if(!r.issues||r.issues.length===0)return null;let n=r.issues[0];if(!n)return"Input validation error";let i=Dt(n?.path);return i?`Input validation error: ${n.message} at ${i}`:`Input validation error: ${n.message}`}async function Jt(e,t){return Rt(e,t[qe])}function Vt(e,t){if(!t.outputSchema||e.isError)return null;if(e.structuredContent===void 0)return`Output validation error: Tool ${t.name} has an output schema but no structured content was provided`;let r=me(e.structuredContent,t.outputSchema);return r?`Output validation error: ${r.message}`:null}function Wt(e){return x(e)&&Array.isArray(e.content)}function qt(e){if(typeof e=="string")return e;try{return JSON.stringify(e)??String(e)}catch{return String(e)}}function Ut(e){if(Wt(e))return e;let t=ze(e);return{content:[{type:"text",text:qt(e)}],...t!==void 0?{structuredContent:t}:{},isError:!1}}function Ht(e){for(let t of e.content??[])if(t.type==="text"&&"text"in t&&typeof t.text=="string")return t.text;return null}function Ft(e){if(e.isError)throw O(Ht(e)?.replace(/^Error:\s*/i,"").trim()||X);let t=e.metadata;if(t&&typeof t=="object"&&t.willNavigate)return null;try{return JSON.stringify(e)}catch{throw O(X)}}function Bt(e,t){return t?t.aborted?Promise.reject(O(ye)):new Promise((r,n)=>{let i=()=>{d(),n(O(ye))},d=()=>{t.removeEventListener("abort",i)};t.addEventListener("abort",i,{once:!0}),e.then(o=>{d(),r(o)},o=>{d(),n(o)})}):e}function Ue(){return typeof navigator<"u"?navigator:null}function He(){return typeof document<"u"?document:null}function Kt(e,t,r){Object.defineProperty(e,t,{configurable:!0,enumerable:!0,writable:!1,value:r})}function We(e,t){Object.defineProperty(e,"modelContext",{configurable:!0,enumerable:!0,writable:!1,value:t})}var L=!1;function Gt(e,t){Object.defineProperty(e,"modelContext",{configurable:!0,enumerable:!0,get(){return L||(L=!0,console.warn("[WebMCPPolyfill] navigator.modelContext is deprecated. The May 27, 2026 WebMCP draft moved the modelContext getter from Navigator to Document \u2014 use document.modelContext instead. See https://github.com/webmachinelearning/webmcp/pull/184.")),t}})}function Fe(e){let t=Ue(),r=He();if(!t&&!r||r?.modelContext)return;let i=t?.modelContext,d=!!i;if(g.installed&&Yt(),r&&i){g.previousDocumentModelContextDescriptor=Object.getOwnPropertyDescriptor(r,"modelContext"),We(r,i),g.installedDocumentModelContext=!0,g.installed=!0;return}if(d)return;let o=new Ct,s=o;if(s[Pt]=!0,r&&(g.previousDocumentModelContextDescriptor=Object.getOwnPropertyDescriptor(r,"modelContext"),We(r,s),g.installedDocumentModelContext=!0),t){g.previousNavigatorModelContextDescriptor=Object.getOwnPropertyDescriptor(t,"modelContext"),g.previousNavigatorModelContextTestingDescriptor=Object.getOwnPropertyDescriptor(t,"modelContextTesting"),L=!1,Gt(t,s),g.installedNavigatorModelContext=!0;let h=e?.installTestingShim??"if-missing",b=!!t.modelContextTesting;(h==="always"||(h===!0||h==="if-missing")&&!b)&&(Kt(t,"modelContextTesting",o.getTestingShim()),g.installedNavigatorModelContextTesting=!0)}g.installed=!0}function Yt(){if(!g.installed)return;let e=(n,i,d)=>{if(d){Object.defineProperty(n,i,d);return}delete n[i]},t=Ue(),r=He();r&&g.installedDocumentModelContext&&e(r,"modelContext",g.previousDocumentModelContextDescriptor),t&&g.installedNavigatorModelContext&&e(t,"modelContext",g.previousNavigatorModelContextDescriptor),t&&g.installedNavigatorModelContextTesting&&e(t,"modelContextTesting",g.previousNavigatorModelContextTestingDescriptor),g.installed=!1,g.previousDocumentModelContextDescriptor=void 0,g.previousNavigatorModelContextDescriptor=void 0,g.previousNavigatorModelContextTestingDescriptor=void 0,g.installedDocumentModelContext=!1,g.installedNavigatorModelContext=!1,g.installedNavigatorModelContextTesting=!1,L=!1}if(typeof window<"u"&&typeof document<"u"){let e=window.__webMCPPolyfillOptions;if(e?.autoInitialize!==!1)try{Fe(e)}catch(t){console.error("[WebMCPPolyfill] Auto-initialization failed:",t)}}export{Fe as initializeWebMCPPolyfill};
|
|
1
|
+
var Ke=Object.defineProperty;var we=e=>{throw TypeError(e)};var Xe=(e,t,n)=>t in e?Ke(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var re=(e,t,n)=>Xe(e,typeof t!="symbol"?t+"":t,n),ie=(e,t,n)=>t.has(e)||we("Cannot "+n);var u=(e,t,n)=>(ie(e,t,"read from private field"),n?n.call(e):t.get(e)),M=(e,t,n)=>t.has(e)?we("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(e):t.set(e,n),L=(e,t,n,o)=>(ie(e,t,"write to private field"),o?o.call(e,n):t.set(e,n),n),R=(e,t,n)=>(ie(e,t,"access private method"),n);var Qe="Failed to parse input arguments",ve="Tool was executed but the invocation failed. For example, the script function threw an error";var et=/^[A-Za-z0-9_.-]{1,128}$/u;function K(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function Z(e){if(typeof e=="symbol")throw new TypeError("Symbol values cannot be converted to a DOMString");return String(e)}function Ee(e){let t=Reflect.get(e,"name"),n=Reflect.get(e,"description"),o=Reflect.get(e,"title");if(t===void 0)throw new TypeError('Tool "name" is required');if(n===void 0)throw new TypeError('Tool "description" is required');let r=Reflect.get(e,"annotations"),i=K(r)?r:{},s=Reflect.get(e,"inputSchema"),a=Reflect.get(e,"outputSchema"),h=Reflect.get(e,"execute");return{name:Z(t),...o===void 0?{}:{title:Z(o).toWellFormed()},description:Z(n),...s===void 0?{}:{inputSchema:s},...a===void 0?{}:{outputSchema:a},execute:h,...r===void 0?{}:{annotations:{...i.title===void 0?{}:{title:Z(i.title).toWellFormed()},readOnlyHint:!!i.readOnlyHint,...i.destructiveHint===void 0?{}:{destructiveHint:!!i.destructiveHint},...i.idempotentHint===void 0?{}:{idempotentHint:!!i.idempotentHint},...i.openWorldHint===void 0?{}:{openWorldHint:!!i.openWorldHint},untrustedContentHint:!!i.untrustedContentHint}}}}function D(e){return new DOMException(e,"UnknownError")}function Se(e){return D(e instanceof Error?`${ve}: ${e.message}`:ve)}function z(e){return new DOMException(e,"InvalidStateError")}function Te(e){if(e.name==="")throw z('Tool "name" must be a non-empty string');if(typeof e.name!="string"||!et.test(e.name))throw z('Tool "name" must be 1\u2013128 characters and contain only ASCII alphanumeric, underscore, hyphen, or period');if(typeof e.description!="string"||e.description.length===0)throw z('Tool "description" must be a non-empty string');if(typeof e.execute!="function")throw new TypeError('Tool "execute" must be a function')}function Me(e){return{readOnlyHint:e.readOnlyHint??!1,untrustedContentHint:e.untrustedContentHint??!1}}function Oe(e){try{let t=JSON.parse(e);if(Array.isArray(t)||K(t))return t}catch{}throw D(Qe)}function xe(e){if(typeof e=="object"&&e!==null||typeof e=="function")try{let t=JSON.stringify(e);if(t)return t}catch{}return String(e)||"Operation succeeded"}function se(e,t,n=()=>t?.reason){return t?t.aborted?Promise.reject(n()):new Promise((o,r)=>{let i=()=>{s(),r(n())},s=()=>t.removeEventListener("abort",i);t.addEventListener("abort",i,{once:!0}),e.then(a=>{s(),o(a)},a=>{s(),r(a)})}):e}function tt(e){let t=e.origin==="null"?e:new URL(e.origin),n=t.protocol;if(["https:","wss:","file:","chrome-extension:","moz-extension:"].includes(n))return!0;let o=t.hostname.toLowerCase(),r=o.split("."),i=r.length===4&&r.every(s=>/^\d{1,3}$/u.test(s)&&Number(s)<=255)&&Number(r[0])===127;return o==="::1"||o==="[::1]"||o==="localhost"||o==="localhost."||o.endsWith(".localhost")||o.endsWith(".localhost.")||i}function ae(e){for(let t of e??[]){let n;try{n=new URL(t)}catch{throw new DOMException(`Invalid or untrustworthy origin: ${String(t)}`,"SecurityError")}if(!tt(n))throw new DOMException(`Invalid or untrustworthy origin: ${t}`,"SecurityError")}}function V(e){if(nt(),!e)return;let t=e.defaultView?.DOMException??DOMException,n=!1;try{let i=e.defaultView;n=!!(i&&i.document===e)}catch{}if(!n)throw new t("The associated document is not fully active","InvalidStateError");let o=Reflect.get(e,"permissionsPolicy")??Reflect.get(e,"featurePolicy");if(o&&typeof o=="object"){let i=Reflect.get(o,"features"),s=Reflect.get(o,"allowsFeature");if(typeof i=="function"&&typeof s=="function"){let a=Reflect.apply(i,o,[]);if(Array.isArray(a)&&a.includes("tools")){if(Reflect.apply(s,o,["tools"])===!0)return;throw new t("WebMCP is disabled by Permissions Policy","NotAllowedError")}}}let r=e.defaultView;if(!(!r||r.parent===r)){try{r.parent.document;return}catch{}throw new t("WebMCP in cross-origin frames requires native Permissions Policy support","NotAllowedError")}}function nt(){if(globalThis.originAgentCluster===!1&&globalThis.location?.protocol!=="file:")throw new DOMException("","SecurityError")}function Pe(e){try{if(new URL(String(e)).origin!=="null")return}catch{}throw new DOMException(`Unsupported tool origin: ${String(e)}`,"NotSupportedError")}function Ae(e){if(e===null||typeof e!="object"&&typeof e!="function")throw new TypeError("inputSchema must be an object");let t=JSON.stringify(e);if(t===void 0)throw new TypeError("inputSchema must be JSON-serializable");return t}var ge=new WeakSet,le=new WeakMap,F=new WeakMap;function We(e){return e.isTrusted&&(ge.has(e)||e.eventPhase!==Event.NONE&&e.target instanceof HTMLFormElement&&F.has(e.target))}function ot(e,t){if(!We(e))throw new DOMException("respondWith() is only available during an agent-invoked submit event","InvalidStateError");if(!e.defaultPrevented)throw new DOMException("respondWith() requires preventDefault() during an agent-invoked submit event","InvalidStateError");if(e.eventPhase===Event.NONE)throw new DOMException("respondWith() is only available while the submit event is being dispatched","InvalidStateError");ge.add(e);let n=Promise.resolve(t);le.set(e,n),e.target instanceof HTMLFormElement&&F.get(e.target)?.respond(e)}var _e=new Set(["email","password","search","tel","text","url"]),rt=new Set([..._e,"date","datetime-local","month","number","time","week"]);function $e(e){return e instanceof HTMLInputElement||e instanceof HTMLSelectElement||e instanceof HTMLTextAreaElement}function ye(e){return Reflect.get(HTMLFormElement.prototype,"elements",e)}function ce(e,t){return Reflect.apply(Element.prototype.getAttribute,e,[t])}function fe(e,t){return Reflect.apply(Element.prototype.hasAttribute,e,[t])}function it(e){return Reflect.get(Node.prototype,"isConnected",e)}function st(e){return Reflect.get(Element.prototype,"shadowRoot",e)}function at(e){return Reflect.apply(HTMLFormElement.prototype.checkValidity,e,[])}function ct(e,t){Reflect.apply(HTMLFormElement.prototype.requestSubmit,e,t?[t]:[])}function ut(e){return[...ye(e)].filter(t=>$e(t)&&!t.matches(":disabled")&&!("readOnly"in t&&t.readOnly&&(t instanceof HTMLTextAreaElement||rt.has(t.type))))}function qe(e){let t=new Map;for(let n of ut(e)){let o=n.name.trim(),r=t.get(o);r?r.push(n):t.set(o,[n])}return t}function Ue(e){return[...e.labels??[]].map(t=>{let n=t.cloneNode(!0);return n instanceof HTMLElement?(n.querySelectorAll("button, input, meter, output, progress, select, textarea").forEach(o=>o.remove()),n.textContent?.trim()??""):""}).filter(Boolean).join("; ")}function lt(e,t){for(let n=t[0]?.parentElement;n&&n!==e;n=n.parentElement)if(n instanceof HTMLFieldSetElement&&t.every(o=>n.contains(o)))return n}function ft(e,t){if(t.length===1){let n=t[0];return n&&(n.getAttribute("toolparamdescription")||Ue(n)||n.getAttribute("aria-description"))||void 0}return lt(e,t)?.getAttribute("toolparamdescription")||void 0}function m(e,t,n,o){let r=ft(t,n),i=r&&o?`${r} (${o})`:r||o;return i?{...e,description:i}:e}function Ce(e,t){let n=e.getAttribute(t);if(n===null||n.trim()==="")return;let o=Number(n);return Number.isFinite(o)?o:void 0}function pt(e,t){let n=e/t;return Math.abs(n-Math.round(n))<Number.EPSILON*16}function ze(e){let t=e.getAttribute("pattern");if(t!==null)try{return new RegExp(t,"v"),t}catch{return}}function Ie(e,t=!0){let n={type:"number"},o=Ce(e,"min"),r=Ce(e,"max");o!==void 0&&(n.minimum=o),r!==void 0&&(n.maximum=r);let i=e.getAttribute("step");if(i!=="any"){let a=i===null||i===""?1:Number(i),h=Number.isFinite(a)&&a>0?a:1,g=Number(e.getAttribute("value"));pt(o??(Number.isFinite(g)?g:0),h)&&(n.multipleOf=h)}let s=t?ze(e):void 0;return s!==void 0&&(n.pattern=s),n}function Le(e,t){let n=e.getAttribute("step"),o=n===null||n===""?60:Number(n),r=Number.isFinite(o)&&o>0?o:60;return r<1?`${t}(:[0-5][0-9](\\.[0-9]{1,3})?)?$`:r<60?`${t}(:[0-5][0-9])?$`:`${t}$`}function dt(e){return{anyOf:e.map(t=>({type:"string",const:t.value,title:t.textContent??""})),enum:e.map(t=>t.value)}}function ue(e){return{anyOf:e.map(t=>{let n=Ue(t);return{type:"string",const:t.value,...n?{title:n}:{}}}),enum:e.map(t=>t.value)}}function Ve(e,t){let n=t[0];if(n){if(t.length>1)return t.every(o=>o instanceof HTMLInputElement)?t.every(o=>o.type==="checkbox")?m({type:"array",items:{type:"string",...ue(t)},uniqueItems:!0},e,t):t.every(o=>o.type==="radio")?m({type:"string",...ue(t)},e,t):void 0:void 0;if(n instanceof HTMLTextAreaElement)return m({type:"string"},e,t);if(n instanceof HTMLSelectElement){let o=dt([...n.options]);return m(n.multiple?{type:"array",items:{type:"string",...o},uniqueItems:!0}:{type:"string",...o},e,t)}if(_e.has(n.type)){let o={type:"string"},r=ze(n);return r!==void 0&&(o.pattern=r),m(o,e,t)}if(n.type==="hidden")return n.getAttribute("toolparamdescription")?m({type:"string"},e,t):void 0;if(n.type==="number")return m(Ie(n),e,t);if(n.type==="range"){let o=Ie(n,!1);return o.minimum??(o.minimum=0),o.maximum??(o.maximum=100),m(o,e,t)}if(n.type==="checkbox")return m({type:"boolean"},e,t);if(n.type==="radio")return m({type:"string",...ue([n])},e,t);if(n.type==="date")return m({type:"string",format:"date"},e,t,"Dates MUST be provided in 'YYYY-MM-DD' format.");if(n.type==="month")return m({type:"string",format:"^[0-9]{4}-(0[1-9]|1[0-2])$"},e,t);if(n.type==="week")return m({type:"string",format:"^[0-9]{4}-W(0[1-9]|[1-4][0-9]|5[0-3])$"},e,t);if(n.type==="time")return m({type:"string",format:Le(n,"^([01][0-9]|2[0-3]):[0-5][0-9]")},e,t);if(n.type==="datetime-local")return m({type:"string",format:Le(n,"^[0-9]{4}-(0[1-9]|1[0-2])-[0-9]{2}T([01][0-9]|2[0-3]):[0-5][0-9]")},e,t);if(n.type==="color")return m({type:"string",format:"^#[0-9a-zA-Z]{6}$"},e,t)}}function mt(e){let t={},n=[];for(let[o,r]of qe(e)){if(!o)continue;let i=Ve(e,r);i&&(Object.defineProperty(t,o,{configurable:!0,enumerable:!0,value:i,writable:!0}),r.some(s=>s.required)&&n.push(o))}return{type:"object",properties:t,required:n}}function ht(e){return{name:ce(e,"toolname")??"",title:ce(e,"tooltitle")??"",description:ce(e,"tooldescription")??"",inputSchema:mt(e),autosubmit:fe(e,"toolautosubmit")}}function b(e){if(typeof e=="string"||typeof e=="boolean"||typeof e=="number"&&Number.isFinite(e))return String(e)}function Be(e){if(typeof e=="boolean")return e;if(typeof e=="number"&&Number.isInteger(e))return e!==0;if(typeof e=="string"){if(e==="1"||e.toLowerCase()==="true")return!0;if(e==="0"||e.toLowerCase()==="false")return!1}}function Re(e,t){if(!Array.isArray(e))return!1;let n=new Set(t);for(let o of e){let r=b(o);if(r===void 0||!n.delete(r))return!1}return!0}function gt(e,t){if(t==="")return e.type!=="number"&&e.type!=="range";let n=e.ownerDocument.createElement("input");return n.type=e.type,n.value=t,n.value!==""}function yt(e,t,n){let o=t[0];if(!o||!Ve(e,t))return!1;if(t.length>1){if(!t.every(i=>i instanceof HTMLInputElement))return!1;if(t.every(i=>i.type==="checkbox"))return Re(n,new Set(t.map(i=>i.value)));if(t.every(i=>i.type==="radio")){let i=b(n);return i!==void 0&&t.some(s=>s.value===i)}return!1}if(o instanceof HTMLSelectElement){let i=new Set([...o.options].map(a=>a.value));if(o.multiple)return Re(n,i);let s=b(n);return s!==void 0&&i.has(s)}if(o instanceof HTMLTextAreaElement)return b(n)!==void 0;if(o.type==="checkbox")return Be(n)!==void 0;if(o.type==="radio"){let i=b(n);return i!==void 0&&o.value===i}let r=b(n);return r!==void 0&>(o,r)}function N(e){e.dispatchEvent(new Event("input",{bubbles:!0,composed:!0})),e.dispatchEvent(new Event("change",{bubbles:!0}))}function bt(e,t){let n=e instanceof HTMLInputElement?HTMLInputElement.prototype:HTMLTextAreaElement.prototype;Object.getOwnPropertyDescriptor(n,"value")?.set?.call(e,t)}function X(e,t){Object.getOwnPropertyDescriptor(HTMLInputElement.prototype,"checked")?.set?.call(e,t)}function wt(e,t){let n=e[0];if(!n)return;if(e.length>1&&e.every(r=>r instanceof HTMLInputElement)){if(e.every(s=>s.type==="checkbox")&&Array.isArray(t)){let s=new Set(t.map(b));for(let a of e){let h=s.has(a.value);a.checked!==h&&(X(a,h),N(a))}return}let r=b(t),i=e.find(s=>s.value===r);i&&!i.checked&&(X(i,!0),N(i));return}if(n instanceof HTMLSelectElement){if(n.multiple&&Array.isArray(t)){let i=new Set(t.map(b)),s=!1;for(let a of n.options){let h=i.has(a.value);a.selected!==h&&(a.selected=h,s=!0)}s&&N(n);return}let r=b(t);r!==void 0&&n.value!==r&&(n.value=r,N(n));return}if(n instanceof HTMLInputElement&&n.type==="checkbox"){let r=Be(t);r!==void 0&&n.checked!==r&&(X(n,r),N(n));return}if(n instanceof HTMLInputElement&&n.type==="radio"){b(t)===n.value&&!n.checked&&(X(n,!0),N(n));return}let o=b(t);o!==void 0&&n.value!==o&&(bt(n,o),N(n))}function vt(e,t){if(Array.isArray(t))throw new TypeError("Declarative tool input must be an object");let n=qe(e);for(let[o,r]of Object.entries(t)){let i=n.get(o);if(!i||!yt(e,i,r))throw new TypeError(`Invalid value for declarative form parameter "${o}"`)}for(let[o,r]of Object.entries(t))wt(n.get(o)??[],r)}function Et(e){return[...ye(e)].find(t=>!t.matches(":disabled")&&(t instanceof HTMLButtonElement&&t.type==="submit"||t instanceof HTMLInputElement&&["image","submit"].includes(t.type)))}function St(e){let t=[...ye(e)].filter(n=>$e(n)&&n.willValidate&&!n.validity.valid).map(n=>`${n.name.trim()||"{unknown}"}: ${n.validationMessage}`).join(". ");return new DOMException(`Form validation failed: ${t}`,"UnknownError")}function De(e){let t=new Event("toolactivated");return Object.defineProperty(t,"toolName",{enumerable:!0,value:e}),t}function Tt(e,t,n,o){let{form:r}=e;return e.cancelPending?.(new DOMException("Tool execution cancelled","UnknownError")),new Promise((i,s)=>{let a=!1,h=()=>{Reflect.apply(EventTarget.prototype.removeEventListener,r,["invalid",S,!0]),F.delete(r),e.cancelPending===O&&delete e.cancelPending},g=d=>{a||(a=!0,h(),d())},O=d=>g(()=>s(d)),$=d=>{d.then(y=>g(()=>i(y)),y=>g(()=>s(y)))},S=d=>{d.isTrusted&&queueMicrotask(()=>{at(r)||O(St(r))})};if(F.set(r,{complete(d){queueMicrotask(()=>{let y=le.get(d);y?$(y):d.defaultPrevented?O(new DOMException("preventDefault() requires respondWith()","UnknownError")):g(()=>i(void 0))})},direct(){g(()=>i(void 0))},respond(d){queueMicrotask(()=>{let y=le.get(d);y&&$(y)})}}),e.cancelPending=O,Reflect.apply(EventTarget.prototype.addEventListener,r,["invalid",S,!0]),!n){o?.focus(),window.dispatchEvent(De(t));return}try{ct(r,o),window.dispatchEvent(De(t))}catch(d){O(d)}})}function Mt(e,t){let n=!0,o=new Map,r=new Map,i=new Map,s=c=>{if(!(c instanceof SubmitEvent)||!c.isTrusted||!(c.target instanceof HTMLFormElement))return;let f=F.get(c.target);f&&(ge.add(c),f.complete(c))},a=c=>{if(!c.isTrusted||!(c.target instanceof HTMLFormElement))return;let f=c.target;queueMicrotask(()=>{c.defaultPrevented||o.get(f)?.cancelPending?.(new DOMException("Tool execution cancelled by form reset","UnknownError"))})};function h(c){i.get(c)?.disconnect(),i.delete(c),c.removeEventListener("reset",a,!0),c.removeEventListener("submit",s,!0)}function g(c){if(i.has(c))return;let f=new MutationObserver(O);i.set(c,f),f.observe(c,{attributes:!0,characterData:!0,childList:!0,subtree:!0}),c.addEventListener("reset",a,!0),c.addEventListener("submit",s,!0)}function O(){g(e);for(let l of i.keys())l instanceof ShadowRoot&&!Reflect.get(Node.prototype,"isConnected",l.host)&&h(l);let c=new Set,f=new Map,Y=new Map;for(let l of i.keys())for(let p of l.querySelectorAll("*")){let G=st(p);if(G&&g(G),!(p instanceof HTMLFormElement)||!fe(p,"toolname")||!fe(p,"tooldescription")||!it(p))continue;let w=p;c.add(w);let I=ht(w),x=JSON.stringify(I),q=r.get(w);if(q===x)continue;let Ze=q!==void 0;r.delete(w);let U=Y.get(I.name);if(U&&!Ze){r.set(w,x);continue}if(U){let be=f.get(U);be&&(r.set(U,be.fingerprint),f.delete(U))}Y.set(I.name,w),f.set(w,{definition:I,fingerprint:x})}for(let l of r.keys())c.has(l)||r.delete(l);for(let[l,p]of o)f.get(l)?.fingerprint!==p.fingerprint&&(p.cancelPending?.(new DOMException("Tool execution cancelled because its form changed","UnknownError")),p.controller.abort(),o.delete(l));for(let[l,{definition:p,fingerprint:G}]of f){if(o.has(l))continue;let w=new AbortController,I={controller:w,fingerprint:G,form:l};o.set(l,I),t.registerTool({name:p.name,title:p.title,description:p.description,inputSchema:p.inputSchema,execute(x){let q=Et(l);if(!p.autosubmit&&!q)throw new DOMException("A declarative form without toolautosubmit requires a submit button","UnknownError");return vt(l,x),Tt(I,p.name,p.autosubmit,q)}},{signal:w.signal}).catch(x=>{w.abort(),x?.name!=="AbortError"&&console.error(`[webmcp] declarative form tool "${p.name}" was not registered:`,x)})}}let $=()=>{},S=e.defaultView?.Element.prototype,d=S?Object.getOwnPropertyDescriptor(S,"attachShadow"):void 0;if(S&&d?.configurable){let c=S.attachShadow,f=function(Y){let l=c.call(this,Y);return n&&l.mode==="open"&&Reflect.get(Node.prototype,"ownerDocument",this)===e&&Reflect.get(Node.prototype,"isConnected",this)&&g(l),l};Object.defineProperty(S,"attachShadow",{...d,value:f}),$=()=>{S.attachShadow===f&&Object.defineProperty(S,"attachShadow",d)}}let y=()=>{},C=e.defaultView?.HTMLFormElement.prototype,oe=C?Object.getOwnPropertyDescriptor(C,"submit"):void 0;if(C&&oe?.configurable){let c=C.submit,f=function(){c.call(this),n&&F.get(this)?.direct()};Object.defineProperty(C,"submit",{...oe,value:f}),y=()=>{C.submit===f&&Object.defineProperty(C,"submit",oe)}}return O(),()=>{n=!1,y(),$();for(let c of i.keys())h(c);r.clear();for(let c of o.values())c.cancelPending?.(new DOMException("Tool execution cancelled","UnknownError")),c.controller.abort();o.clear()}}var Ot="__isWebMCPPolyfill",Q=Symbol("registeredInputSchema"),B=Symbol("registrationSignal"),Ne=Symbol("registrationAbort"),te=[],ee=null,pe=null;function je(){return typeof globalThis.origin=="string"?globalThis.origin:globalThis.location?.origin??""}function W(e,t,n){let o=Object.getOwnPropertyDescriptor(e,t);try{Object.defineProperty(e,t,n)}catch(r){throw Ge(),r}te.push({target:e,key:t,previous:o})}var v,j,P,J,H,A,E,de,me,he,ke,T=(ke=class extends EventTarget{constructor(t){super();M(this,E);M(this,v,new Map);M(this,j,null);M(this,P,null);M(this,J,t=>{u(this,P)?.call(this,t)});M(this,H);M(this,A);L(this,A,t),L(this,H,t?.defaultView?.DOMException??DOMException),Object.defineProperty(this,Ot,{value:!0,enumerable:!1,writable:!1,configurable:!1})}get ontoolchange(){return u(this,P)}set ontoolchange(t){let n=typeof t=="function"?t:null;if(n===null){L(this,P,null),super.removeEventListener("toolchange",u(this,J));return}u(this,P)===null&&super.addEventListener("toolchange",u(this,J)),L(this,P,n)}async registerTool(t,n={}){V(u(this,A));let o=n?.signal,r=Pt(t,u(this,v));if(o?.throwIfAborted(),ae(n?.exposedTo),o?.throwIfAborted(),n?.exposedTo?.length)throw new(u(this,H))("Cross-document tool exposure requires native WebMCP","NotSupportedError");if(u(this,v).set(r.name,r),o){let i=()=>{R(this,E,de).call(this,r.name,r)&&R(this,E,he).call(this)};r[B]=o,r[Ne]=i,o.addEventListener("abort",i,{once:!0})}if(await R(this,E,he).call(this),o?.aborted)throw o.reason}async getTools(t={}){if(V(u(this,A)),ae(t?.fromOrigins),t?.fromOrigins?.length)throw new(u(this,H))("Cross-document tool discovery requires native WebMCP","NotSupportedError");let n=[...u(this,v).values()].map(o=>{let r=o[Q],i=r===void 0?void 0:JSON.parse(r);return{name:o.name,title:o.title??"",description:o.description,...K(i)?{inputSchema:i}:{},origin:je(),window:globalThis.window,...o.annotations?{annotations:Me(o.annotations)}:{}}}).sort((o,r)=>o.name<r.name?-1:o.name>r.name?1:0);return await new Promise(o=>setTimeout(o,0)),n}async executeTool(t,n,o={}){if(V(u(this,A)),t===null||typeof t!="object")throw new TypeError("RegisteredTool must be an object");for(let r of["name","description","window","origin"])if(!(r in t))throw new TypeError(`RegisteredTool.${r} is required`);if(Pe(t.origin),t.window!==globalThis.window||t.origin!==je())throw D(`Tool not found: ${t.name}`);return R(this,E,me).call(this,t.name,n,o)}static getTestingShim(t){return u(t,j)??L(t,j,new xt(t)),u(t,j)}static getToolInfos(t){return[...u(t,v).values()].map(n=>({name:n.name,description:n.description,...n[Q]===void 0?{}:{inputSchema:n[Q]}}))}static executeToolForTesting(t,n,o,r){var i;return V(u(t,A)),R(i=t,E,me).call(i,n,o,r)}static dispose(t){var n;for(let o of u(t,v).keys())R(n=t,E,de).call(n,o);t.ontoolchange=null,u(t,j)?.dispose()}},v=new WeakMap,j=new WeakMap,P=new WeakMap,J=new WeakMap,H=new WeakMap,A=new WeakMap,E=new WeakSet,de=function(t,n){let o=u(this,v).get(t);if(!o||n&&o!==n)return!1;let r=o[B],i=o[Ne];return r&&i&&r.removeEventListener("abort",i),u(this,v).delete(t)},me=async function(t,n,o){o?.signal?.throwIfAborted();let r=u(this,v).get(t);if(!r)throw D(`Tool not found: ${t}`);let i=Oe(n);if(o?.signal?.throwIfAborted(),r[B]?.aborted)throw D("Tool unregistered");let s;try{let a=r[B];s=await se(se(Promise.resolve(r.execute(i)),a,()=>D("Tool unregistered")),o?.signal)}catch(a){throw o?.signal?.aborted&&a===o.signal.reason||r[B]?.aborted?a:Se(a)}return xe(s)},he=async function(){await new Promise(t=>setTimeout(t,0)),this.dispatchEvent(new Event("toolchange")),u(this,j)?.dispatchToolChange()},ke),_=function(){throw new TypeError("Illegal constructor")};Object.defineProperty(_,"name",{value:"ModelContext"});Object.defineProperty(_,"prototype",{value:T.prototype,writable:!1});Object.setPrototypeOf(_,EventTarget);Object.defineProperty(T.prototype,"constructor",{configurable:!0,writable:!0,value:_});Object.defineProperty(T.prototype,Symbol.toStringTag,{configurable:!0,value:"ModelContext"});for(let e of["registerTool","getTools","executeTool","ontoolchange"]){let t=Object.getOwnPropertyDescriptor(T.prototype,e);t&&Object.defineProperty(T.prototype,e,{...t,enumerable:!0})}var k,Fe,xt=(Fe=class extends EventTarget{constructor(t){super();re(this,"_ontoolchange",null);re(this,"ontoolchangeListener",t=>{this._ontoolchange?.call(this,t)});M(this,k);L(this,k,t)}listTools(){return T.getToolInfos(u(this,k))}executeTool(t,n,o){return T.executeToolForTesting(u(this,k),t,n,o)}get ontoolchange(){return this._ontoolchange}set ontoolchange(t){let n=typeof t=="function"?t:null;if(n===null){this._ontoolchange=null,super.removeEventListener("toolchange",this.ontoolchangeListener);return}this._ontoolchange===null&&super.addEventListener("toolchange",this.ontoolchangeListener),this._ontoolchange=n}dispatchToolChange(){this.dispatchEvent(new Event("toolchange"))}dispose(){this.ontoolchange=null}},k=new WeakMap,Fe);function Pt(e,t){if(!e||typeof e!="object")throw new TypeError("registerTool(tool) requires a tool object");let n=Ee(e);if(Te(n),t.has(n.name))throw z(`Tool already registered: ${n.name}`);let o=n.inputSchema===void 0?void 0:Ae(n.inputSchema);return{name:n.name,...n.title===void 0?{}:{title:n.title},description:n.description,...n.inputSchema===void 0?{}:{inputSchema:n.inputSchema},...n.annotations===void 0?{}:{annotations:n.annotations},execute:r=>Reflect.apply(n.execute,void 0,[r]),...o!==void 0?{[Q]:o}:{}}}var ne=!1,Je=new WeakMap,{modelContext:Ye}={modelContext(){if(!(this instanceof Document))throw new TypeError("Illegal invocation");return Je.get(this)}};Object.defineProperty(Ye,"name",{value:"get modelContext"});function He(e,t){Je.set(e,t),!Object.hasOwn(Document.prototype,"modelContext")&&W(Document.prototype,"modelContext",{configurable:!0,enumerable:!0,get:Ye})}function At(e,t){W(e,"modelContext",{configurable:!0,enumerable:!0,get(){return ne||(ne=!0,console.warn("[WebMCPPolyfill] navigator.modelContext is deprecated. The May 27, 2026 WebMCP draft moved the modelContext getter from Navigator to Document \u2014 use document.modelContext instead. See https://github.com/webmachinelearning/webmcp/pull/184.")),t}})}function Ct(){let e=SubmitEvent.prototype;"agentInvoked"in e||W(e,"agentInvoked",{configurable:!0,enumerable:!0,get(){return We(this)}}),"respondWith"in e||W(e,"respondWith",{configurable:!0,enumerable:!0,writable:!0,value(t){ot(this,t)}})}function It(e){if(globalThis.isSecureContext===!1)return;let t=typeof navigator>"u"?null:navigator,n=typeof document>"u"?null:document;if(!t||!n||typeof window>"u"||n.modelContext)return;let o=t.modelContext;if(te.length>0&&Ge(),o){He(n,o);return}let r=Object.getOwnPropertyDescriptor(window,"ModelContext");if(r&&!r.configurable){if(!Object.is(Reflect.get(window,"ModelContext"),_))throw new TypeError("Cannot install ModelContext over a non-configurable global")}else W(window,"ModelContext",{configurable:!0,enumerable:!1,writable:!0,value:_});let i=new T(n);ee=i,He(n,i),ne=!1,At(t,i),Ct(),e?.installTestingShim&&!t.modelContextTesting&&W(t,"modelContextTesting",{configurable:!0,enumerable:!0,writable:!1,value:T.getTestingShim(i)}),pe=Mt(n,i)}function Ge(){pe?.(),pe=null,ee&&T.dispose(ee),ee=null;for(let{target:e,key:t,previous:n}of[...te].reverse())n?Object.defineProperty(e,t,n):Reflect.deleteProperty(e,t);te.length=0,ne=!1}export{It as initializeWebMCPPolyfill};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
var C="webmcp:",T=t=>t.startsWith(C)?t.slice(C.length):t,d={warn(t,...e){typeof console<"u"&&typeof console.warn=="function"&&console.warn(`[Persona/WebMCP] ${t}`,...e)}},m=class{constructor(e,n){this.config=e;this.deps=n;this.installed=!1;this.readyPromise=null;this.incompatibleContextWarned=!1;this.confirmHandler=e.onConfirm??null,this.timeoutMs=3e4}setConfirmHandler(e){this.confirmHandler=e}isOperational(){return this.config.enabled!==!0||!this.installed?!1:this.getModelContext()!==null}async snapshotForDispatch(){if(await this.ensureReady(),this.config.enabled!==!0)return[];let e=this.getModelContext();if(!e)return[];let n;try{n=await e.getTools()}catch(i){return d.warn("getTools() threw: shipping an empty WebMCP snapshot.",i),[]}this.deps.recordToolDisplayTitles(n);let o=typeof location<"u"?location.origin:"";return n.filter(i=>this.passesClientAllowlist(i.name)).map(i=>{let l=W(i.annotations);return{name:i.name,description:i.description,parametersSchema:P(i.inputSchema),origin:"webmcp",...o?{pageOrigin:o}:{},...l?{annotations:l}:{},...l?.untrustedContentHint===!0?{untrustedContentHint:!0}:{}}})}async executeToolCall(e,n,o){if(await this.ensureReady(),this.config.enabled!==!0)return s("WebMCP is not enabled on this widget.");let i=this.getModelContext();if(!i){let r=typeof document<"u"&&!!document.modelContext;return s(r?"WebMCP is not operational: document.modelContext is present but does not expose the strict getTools()/executeTool() surface (likely a different or older WebMCP polyfill).":"WebMCP bridge is not operational on this page (document.modelContext not available).")}let l=T(e),a;try{a=await i.getTools()}catch(r){let p=r instanceof Error?r.message:String(r);return s(`Failed to read WebMCP registry: ${p}`)}this.deps.recordToolDisplayTitles(a);let f=a.find(r=>r.name===l);if(!f)return s(`WebMCP tool not registered on this page: ${l}`);if(!this.passesClientAllowlist(l))return s(`WebMCP tool not allowed by client allowlist: ${l}`);if(o?.aborted)return s("Aborted by cancel()");let b=this.deps.getToolDisplayTitle(l),h={toolName:l,args:n,description:f.description,...b?{title:b}:{},reason:"gate"};if(!await this.requestConfirm(h))return s("User declined the tool call.");if(o?.aborted)return s("Aborted by cancel()");let c=new AbortController,y=!1,M=setTimeout(()=>{y=!0,c.abort()},this.timeoutMs),g=()=>c.abort();o&&(o.aborted?c.abort():o.addEventListener("abort",g,{once:!0}));try{let r=await i.executeTool(f,O(n),{signal:c.signal});return w(r)}catch(r){if(y)return s(`WebMCP tool '${l}' timed out after ${this.timeoutMs}ms`);if(o?.aborted)return s("Aborted by cancel()");let p=r instanceof Error?r.message:String(r);return s(p)}finally{clearTimeout(M),o&&o.removeEventListener("abort",g)}}ensureReady(){return this.config.enabled!==!0?Promise.resolve():(this.readyPromise||(this.readyPromise=this.install()),this.readyPromise)}async install(){try{if(this.getModelContext()){this.installed=!0;return}(await this.deps.loadPolyfill()).initializeWebMCPPolyfill(),this.installed=!0}catch(e){d.warn("Failed to load @mcp-b/webmcp-polyfill: WebMCP consumption disabled.",e),this.installed=!1}}getModelContext(){if(typeof document>"u")return null;let e=document.modelContext;if(!e||typeof e!="object")return null;let n=e;return typeof n.getTools!="function"||typeof n.executeTool!="function"?(this.incompatibleContextWarned||(this.incompatibleContextWarned=!0,d.warn("document.modelContext is present but does not expose getTools()/executeTool(): WebMCP consumption is disabled. Another (incompatible or older) WebMCP polyfill likely installed document.modelContext before Persona. Remove it, or use a polyfill implementing the strict standard surface (e.g. @mcp-b/webmcp-polyfill).")),null):e}async requestConfirm(e){let n=this.confirmHandler??A;try{return await n(e)}catch(o){return d.warn(`Confirm handler threw for WebMCP tool '${e.toolName}'; declining.`,o),!1}}passesClientAllowlist(e){let n=this.config.allowlist;return!n||n.length===0?!0:n.some(o=>x(e,o))}},x=(t,e)=>{if(e==="*")return!0;let n=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+n.replace(/\*/g,".*")+"$").test(t)},u={type:"object",properties:{}},W=t=>{if(!t||typeof t!="object")return;let e={...typeof t.readOnlyHint=="boolean"?{readOnlyHint:t.readOnlyHint}:{},...typeof t.untrustedContentHint=="boolean"?{untrustedContentHint:t.untrustedContentHint}:{}};return Object.keys(e).length>0?e:void 0},P=t=>{if(t===void 0||t==="")return{...u};if(typeof t=="object")return t!==null&&!Array.isArray(t)?t:{...u};try{let e=JSON.parse(t);return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{...u}}catch{return{...u}}},w=t=>{if(t==null)return{content:[{type:"text",text:""}]};let e;try{e=JSON.parse(t)}catch{return{content:[{type:"text",text:t}]}}return e!==null&&typeof e=="object"&&Array.isArray(e.content)?e:{content:[{type:"text",text:typeof e=="string"?e:k(e)}]}},s=t=>({isError:!0,content:[{type:"text",text:t}]}),A=async t=>{if(typeof window>"u"||typeof window.confirm!="function")return!1;let e=v(t.args),n=`Allow the AI to call ${t.toolName}`+(e?`
|
|
2
|
+
|
|
3
|
+
Arguments:
|
|
4
|
+
${e}`:"")+(t.description?`
|
|
5
|
+
|
|
6
|
+
${t.description}`:"");return window.confirm(n)},v=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)}},O=t=>{if(t===void 0)return"{}";try{let e=JSON.stringify(t);return e===void 0?"{}":e}catch{return"{}"}},k=t=>{if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}};export{m as WebMcpBridge};
|
package/dist/webmcp-runtime.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var b=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var w=(t,e)=>{for(var n in e)b(t,n,{get:e[n],enumerable:!0})},A=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of W(e))!P.call(t,r)&&r!==n&&b(t,r,{get:()=>e[r],enumerable:!(o=x(e,r))||o.enumerable});return t};var v=t=>A(b({},"__esModule",{value:!0}),t);var j={};w(j,{WebMcpBridge:()=>f});module.exports=v(j);var h="webmcp:",O=t=>t.startsWith(h)?t.slice(h.length):t,d={warn(t,...e){typeof console<"u"&&typeof console.warn=="function"&&console.warn(`[Persona/WebMCP] ${t}`,...e)}},f=class{constructor(e,n){this.config=e;this.deps=n;this.installed=!1;this.readyPromise=null;this.incompatibleContextWarned=!1;this.confirmHandler=e.onConfirm??null,this.timeoutMs=3e4}setConfirmHandler(e){this.confirmHandler=e}isOperational(){return this.config.enabled!==!0||!this.installed?!1:this.getModelContext()!==null}async snapshotForDispatch(){if(await this.ensureReady(),this.config.enabled!==!0)return[];let e=this.getModelContext();if(!e)return[];let n;try{n=await e.getTools()}catch(r){return d.warn("getTools() threw: shipping an empty WebMCP snapshot.",r),[]}this.deps.recordToolDisplayTitles(n);let o=typeof location<"u"?location.origin:"";return n.filter(r=>this.passesClientAllowlist(r.name)).map(r=>{let l=H(r.annotations);return{name:r.name,description:r.description,parametersSchema:S(r.inputSchema),origin:"webmcp",...o?{pageOrigin:o}:{},...l?{annotations:l}:{},...l?.untrustedContentHint===!0?{untrustedContentHint:!0}:{}}})}async executeToolCall(e,n,o){if(await this.ensureReady(),this.config.enabled!==!0)return s("WebMCP is not enabled on this widget.");let r=this.getModelContext();if(!r){let i=typeof document<"u"&&!!document.modelContext;return s(i?"WebMCP is not operational: document.modelContext is present but does not expose the strict getTools()/executeTool() surface (likely a different or older WebMCP polyfill).":"WebMCP bridge is not operational on this page (document.modelContext not available).")}let l=O(e),a;try{a=await r.getTools()}catch(i){let m=i instanceof Error?i.message:String(i);return s(`Failed to read WebMCP registry: ${m}`)}this.deps.recordToolDisplayTitles(a);let p=a.find(i=>i.name===l);if(!p)return s(`WebMCP tool not registered on this page: ${l}`);if(!this.passesClientAllowlist(l))return s(`WebMCP tool not allowed by client allowlist: ${l}`);if(o?.aborted)return s("Aborted by cancel()");let y=this.deps.getToolDisplayTitle(l),M={toolName:l,args:n,description:p.description,...y?{title:y}:{},reason:"gate"};if(!await this.requestConfirm(M))return s("User declined the tool call.");if(o?.aborted)return s("Aborted by cancel()");let c=new AbortController,g=!1,T=setTimeout(()=>{g=!0,c.abort()},this.timeoutMs),C=()=>c.abort();o&&(o.aborted?c.abort():o.addEventListener("abort",C,{once:!0}));try{let i=await r.executeTool(p,R(n),{signal:c.signal});return D(i)}catch(i){if(g)return s(`WebMCP tool '${l}' timed out after ${this.timeoutMs}ms`);if(o?.aborted)return s("Aborted by cancel()");let m=i instanceof Error?i.message:String(i);return s(m)}finally{clearTimeout(T),o&&o.removeEventListener("abort",C)}}ensureReady(){return this.config.enabled!==!0?Promise.resolve():(this.readyPromise||(this.readyPromise=this.install()),this.readyPromise)}async install(){try{if(this.getModelContext()){this.installed=!0;return}(await this.deps.loadPolyfill()).initializeWebMCPPolyfill(),this.installed=!0}catch(e){d.warn("Failed to load @mcp-b/webmcp-polyfill: WebMCP consumption disabled.",e),this.installed=!1}}getModelContext(){if(typeof document>"u")return null;let e=document.modelContext;if(!e||typeof e!="object")return null;let n=e;return typeof n.getTools!="function"||typeof n.executeTool!="function"?(this.incompatibleContextWarned||(this.incompatibleContextWarned=!0,d.warn("document.modelContext is present but does not expose getTools()/executeTool(): WebMCP consumption is disabled. Another (incompatible or older) WebMCP polyfill likely installed document.modelContext before Persona. Remove it, or use a polyfill implementing the strict standard surface (e.g. @mcp-b/webmcp-polyfill).")),null):e}async requestConfirm(e){let n=this.confirmHandler??I;try{return await n(e)}catch(o){return d.warn(`Confirm handler threw for WebMCP tool '${e.toolName}'; declining.`,o),!1}}passesClientAllowlist(e){let n=this.config.allowlist;return!n||n.length===0?!0:n.some(o=>k(e,o))}},k=(t,e)=>{if(e==="*")return!0;let n=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+n.replace(/\*/g,".*")+"$").test(t)},u={type:"object",properties:{}},H=t=>{if(!t||typeof t!="object")return;let e={...typeof t.readOnlyHint=="boolean"?{readOnlyHint:t.readOnlyHint}:{},...typeof t.untrustedContentHint=="boolean"?{untrustedContentHint:t.untrustedContentHint}:{}};return Object.keys(e).length>0?e:void 0},S=t=>{if(t===void 0||t==="")return{...u};if(typeof t=="object")return t!==null&&!Array.isArray(t)?t:{...u};try{let e=JSON.parse(t);return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{...u}}catch{return{...u}}},D=t=>{if(t==null)return{content:[{type:"text",text:""}]};let e;try{e=JSON.parse(t)}catch{return{content:[{type:"text",text:t}]}}return e!==null&&typeof e=="object"&&Array.isArray(e.content)?e:{content:[{type:"text",text:typeof e=="string"?e:$(e)}]}},s=t=>({isError:!0,content:[{type:"text",text:t}]}),I=async t=>{if(typeof window>"u"||typeof window.confirm!="function")return!1;let e=E(t.args),n=`Allow the AI to call ${t.toolName}`+(e?`
|
|
2
2
|
|
|
3
3
|
Arguments:
|
|
4
4
|
${e}`:"")+(t.description?`
|
|
5
5
|
|
|
6
|
-
${t.description}`:"");return window.confirm(n)},
|
|
6
|
+
${t.description}`:"");return window.confirm(n)},E=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)}},R=t=>{if(t===void 0)return"{}";try{let e=JSON.stringify(t);return e===void 0?"{}":e}catch{return"{}"}},$=t=>{if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}};0&&(module.exports={WebMcpBridge});
|
|
@@ -30,6 +30,14 @@ type ClientToolDefinition = {
|
|
|
30
30
|
readOnlyHint?: boolean;
|
|
31
31
|
untrustedContentHint?: boolean;
|
|
32
32
|
};
|
|
33
|
+
/**
|
|
34
|
+
* Hoisted copy of `annotations.untrustedContentHint`. This is the field the
|
|
35
|
+
* server actually acts on (`InlineClientToolSchema`): it spotlights the
|
|
36
|
+
* tool's output before the model reads it, so instructions embedded in
|
|
37
|
+
* page-provided content (reviews, comments, emails) are not treated as
|
|
38
|
+
* instructions. `annotations` itself is trace/dashboard metadata only.
|
|
39
|
+
*/
|
|
40
|
+
untrustedContentHint?: boolean;
|
|
33
41
|
};
|
|
34
42
|
/**
|
|
35
43
|
* Information passed to the confirm-bubble handler before a `webmcp:*` tool
|
|
@@ -175,8 +183,22 @@ type AgentWidgetWebMcpConfig = {
|
|
|
175
183
|
interface ModelContextToolInfo {
|
|
176
184
|
name: string;
|
|
177
185
|
description: string;
|
|
178
|
-
/**
|
|
179
|
-
|
|
186
|
+
/**
|
|
187
|
+
* JSON Schema for the tool's input, in EITHER generation of the WebMCP
|
|
188
|
+
* contract. Never read it raw: `normalizeInputSchema` in
|
|
189
|
+
* `webmcp-runtime-entry.ts` collapses both shapes to the object the wire
|
|
190
|
+
* needs.
|
|
191
|
+
*
|
|
192
|
+
* `webmcp#241` changed this from a JSON-encoded string to a JSON Schema
|
|
193
|
+
* object. `@mcp-b/webmcp-polyfill` made the switch in v5, and Chrome ships it
|
|
194
|
+
* from 154.0.8013 (cross-document tools first) -- but Chrome 149-153, most of
|
|
195
|
+
* the Origin Trial population, and 154's same-document tools still emit the
|
|
196
|
+
* string. Both are live in the field, so we accept both.
|
|
197
|
+
*
|
|
198
|
+
* Absent when the tool registered no schema: v5 omits the member, where v4
|
|
199
|
+
* always emitted a `{"type":"object"}` string.
|
|
200
|
+
*/
|
|
201
|
+
inputSchema?: object | string;
|
|
180
202
|
/**
|
|
181
203
|
* Display title declared on the tool (`ToolDescriptor.title` in the WebMCP
|
|
182
204
|
* spec). The polyfill returns `""` when the tool didn't declare one. Note:
|
|
@@ -185,6 +207,16 @@ interface ModelContextToolInfo {
|
|
|
185
207
|
* channel available to us.
|
|
186
208
|
*/
|
|
187
209
|
title?: string;
|
|
210
|
+
/**
|
|
211
|
+
* WebMCP `Tool.annotations`. Returned by `getTools()` since
|
|
212
|
+
* `@mcp-b/webmcp-polyfill` v5 (and by Chrome's native implementation);
|
|
213
|
+
* absent on v4 and whenever the tool declared none -- the spec omits the
|
|
214
|
+
* member rather than emitting an empty object.
|
|
215
|
+
*/
|
|
216
|
+
annotations?: {
|
|
217
|
+
readOnlyHint?: boolean;
|
|
218
|
+
untrustedContentHint?: boolean;
|
|
219
|
+
};
|
|
188
220
|
}
|
|
189
221
|
/** The slice of `@mcp-b/webmcp-polyfill` the bridge consumes on install. */
|
|
190
222
|
type WebMcpPolyfillModule = {
|
package/dist/webmcp-runtime.d.ts
CHANGED
|
@@ -30,6 +30,14 @@ type ClientToolDefinition = {
|
|
|
30
30
|
readOnlyHint?: boolean;
|
|
31
31
|
untrustedContentHint?: boolean;
|
|
32
32
|
};
|
|
33
|
+
/**
|
|
34
|
+
* Hoisted copy of `annotations.untrustedContentHint`. This is the field the
|
|
35
|
+
* server actually acts on (`InlineClientToolSchema`): it spotlights the
|
|
36
|
+
* tool's output before the model reads it, so instructions embedded in
|
|
37
|
+
* page-provided content (reviews, comments, emails) are not treated as
|
|
38
|
+
* instructions. `annotations` itself is trace/dashboard metadata only.
|
|
39
|
+
*/
|
|
40
|
+
untrustedContentHint?: boolean;
|
|
33
41
|
};
|
|
34
42
|
/**
|
|
35
43
|
* Information passed to the confirm-bubble handler before a `webmcp:*` tool
|
|
@@ -175,8 +183,22 @@ type AgentWidgetWebMcpConfig = {
|
|
|
175
183
|
interface ModelContextToolInfo {
|
|
176
184
|
name: string;
|
|
177
185
|
description: string;
|
|
178
|
-
/**
|
|
179
|
-
|
|
186
|
+
/**
|
|
187
|
+
* JSON Schema for the tool's input, in EITHER generation of the WebMCP
|
|
188
|
+
* contract. Never read it raw: `normalizeInputSchema` in
|
|
189
|
+
* `webmcp-runtime-entry.ts` collapses both shapes to the object the wire
|
|
190
|
+
* needs.
|
|
191
|
+
*
|
|
192
|
+
* `webmcp#241` changed this from a JSON-encoded string to a JSON Schema
|
|
193
|
+
* object. `@mcp-b/webmcp-polyfill` made the switch in v5, and Chrome ships it
|
|
194
|
+
* from 154.0.8013 (cross-document tools first) -- but Chrome 149-153, most of
|
|
195
|
+
* the Origin Trial population, and 154's same-document tools still emit the
|
|
196
|
+
* string. Both are live in the field, so we accept both.
|
|
197
|
+
*
|
|
198
|
+
* Absent when the tool registered no schema: v5 omits the member, where v4
|
|
199
|
+
* always emitted a `{"type":"object"}` string.
|
|
200
|
+
*/
|
|
201
|
+
inputSchema?: object | string;
|
|
180
202
|
/**
|
|
181
203
|
* Display title declared on the tool (`ToolDescriptor.title` in the WebMCP
|
|
182
204
|
* spec). The polyfill returns `""` when the tool didn't declare one. Note:
|
|
@@ -185,6 +207,16 @@ interface ModelContextToolInfo {
|
|
|
185
207
|
* channel available to us.
|
|
186
208
|
*/
|
|
187
209
|
title?: string;
|
|
210
|
+
/**
|
|
211
|
+
* WebMCP `Tool.annotations`. Returned by `getTools()` since
|
|
212
|
+
* `@mcp-b/webmcp-polyfill` v5 (and by Chrome's native implementation);
|
|
213
|
+
* absent on v4 and whenever the tool declared none -- the spec omits the
|
|
214
|
+
* member rather than emitting an empty object.
|
|
215
|
+
*/
|
|
216
|
+
annotations?: {
|
|
217
|
+
readOnlyHint?: boolean;
|
|
218
|
+
untrustedContentHint?: boolean;
|
|
219
|
+
};
|
|
188
220
|
}
|
|
189
221
|
/** The slice of `@mcp-b/webmcp-polyfill` the bridge consumes on install. */
|
|
190
222
|
type WebMcpPolyfillModule = {
|
package/dist/webmcp-runtime.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
var
|
|
1
|
+
var C="webmcp:",T=t=>t.startsWith(C)?t.slice(C.length):t,d={warn(t,...e){typeof console<"u"&&typeof console.warn=="function"&&console.warn(`[Persona/WebMCP] ${t}`,...e)}},m=class{constructor(e,n){this.config=e;this.deps=n;this.installed=!1;this.readyPromise=null;this.incompatibleContextWarned=!1;this.confirmHandler=e.onConfirm??null,this.timeoutMs=3e4}setConfirmHandler(e){this.confirmHandler=e}isOperational(){return this.config.enabled!==!0||!this.installed?!1:this.getModelContext()!==null}async snapshotForDispatch(){if(await this.ensureReady(),this.config.enabled!==!0)return[];let e=this.getModelContext();if(!e)return[];let n;try{n=await e.getTools()}catch(i){return d.warn("getTools() threw: shipping an empty WebMCP snapshot.",i),[]}this.deps.recordToolDisplayTitles(n);let o=typeof location<"u"?location.origin:"";return n.filter(i=>this.passesClientAllowlist(i.name)).map(i=>{let l=W(i.annotations);return{name:i.name,description:i.description,parametersSchema:P(i.inputSchema),origin:"webmcp",...o?{pageOrigin:o}:{},...l?{annotations:l}:{},...l?.untrustedContentHint===!0?{untrustedContentHint:!0}:{}}})}async executeToolCall(e,n,o){if(await this.ensureReady(),this.config.enabled!==!0)return s("WebMCP is not enabled on this widget.");let i=this.getModelContext();if(!i){let r=typeof document<"u"&&!!document.modelContext;return s(r?"WebMCP is not operational: document.modelContext is present but does not expose the strict getTools()/executeTool() surface (likely a different or older WebMCP polyfill).":"WebMCP bridge is not operational on this page (document.modelContext not available).")}let l=T(e),a;try{a=await i.getTools()}catch(r){let p=r instanceof Error?r.message:String(r);return s(`Failed to read WebMCP registry: ${p}`)}this.deps.recordToolDisplayTitles(a);let f=a.find(r=>r.name===l);if(!f)return s(`WebMCP tool not registered on this page: ${l}`);if(!this.passesClientAllowlist(l))return s(`WebMCP tool not allowed by client allowlist: ${l}`);if(o?.aborted)return s("Aborted by cancel()");let b=this.deps.getToolDisplayTitle(l),h={toolName:l,args:n,description:f.description,...b?{title:b}:{},reason:"gate"};if(!await this.requestConfirm(h))return s("User declined the tool call.");if(o?.aborted)return s("Aborted by cancel()");let c=new AbortController,y=!1,M=setTimeout(()=>{y=!0,c.abort()},this.timeoutMs),g=()=>c.abort();o&&(o.aborted?c.abort():o.addEventListener("abort",g,{once:!0}));try{let r=await i.executeTool(f,O(n),{signal:c.signal});return w(r)}catch(r){if(y)return s(`WebMCP tool '${l}' timed out after ${this.timeoutMs}ms`);if(o?.aborted)return s("Aborted by cancel()");let p=r instanceof Error?r.message:String(r);return s(p)}finally{clearTimeout(M),o&&o.removeEventListener("abort",g)}}ensureReady(){return this.config.enabled!==!0?Promise.resolve():(this.readyPromise||(this.readyPromise=this.install()),this.readyPromise)}async install(){try{if(this.getModelContext()){this.installed=!0;return}(await this.deps.loadPolyfill()).initializeWebMCPPolyfill(),this.installed=!0}catch(e){d.warn("Failed to load @mcp-b/webmcp-polyfill: WebMCP consumption disabled.",e),this.installed=!1}}getModelContext(){if(typeof document>"u")return null;let e=document.modelContext;if(!e||typeof e!="object")return null;let n=e;return typeof n.getTools!="function"||typeof n.executeTool!="function"?(this.incompatibleContextWarned||(this.incompatibleContextWarned=!0,d.warn("document.modelContext is present but does not expose getTools()/executeTool(): WebMCP consumption is disabled. Another (incompatible or older) WebMCP polyfill likely installed document.modelContext before Persona. Remove it, or use a polyfill implementing the strict standard surface (e.g. @mcp-b/webmcp-polyfill).")),null):e}async requestConfirm(e){let n=this.confirmHandler??A;try{return await n(e)}catch(o){return d.warn(`Confirm handler threw for WebMCP tool '${e.toolName}'; declining.`,o),!1}}passesClientAllowlist(e){let n=this.config.allowlist;return!n||n.length===0?!0:n.some(o=>x(e,o))}},x=(t,e)=>{if(e==="*")return!0;let n=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+n.replace(/\*/g,".*")+"$").test(t)},u={type:"object",properties:{}},W=t=>{if(!t||typeof t!="object")return;let e={...typeof t.readOnlyHint=="boolean"?{readOnlyHint:t.readOnlyHint}:{},...typeof t.untrustedContentHint=="boolean"?{untrustedContentHint:t.untrustedContentHint}:{}};return Object.keys(e).length>0?e:void 0},P=t=>{if(t===void 0||t==="")return{...u};if(typeof t=="object")return t!==null&&!Array.isArray(t)?t:{...u};try{let e=JSON.parse(t);return e!==null&&typeof e=="object"&&!Array.isArray(e)?e:{...u}}catch{return{...u}}},w=t=>{if(t==null)return{content:[{type:"text",text:""}]};let e;try{e=JSON.parse(t)}catch{return{content:[{type:"text",text:t}]}}return e!==null&&typeof e=="object"&&Array.isArray(e.content)?e:{content:[{type:"text",text:typeof e=="string"?e:k(e)}]}},s=t=>({isError:!0,content:[{type:"text",text:t}]}),A=async t=>{if(typeof window>"u"||typeof window.confirm!="function")return!1;let e=v(t.args),n=`Allow the AI to call ${t.toolName}`+(e?`
|
|
2
2
|
|
|
3
3
|
Arguments:
|
|
4
4
|
${e}`:"")+(t.description?`
|
|
5
5
|
|
|
6
|
-
${t.description}`:"");return window.confirm(n)},
|
|
6
|
+
${t.description}`:"");return window.confirm(n)},v=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)}},O=t=>{if(t===void 0)return"{}";try{let e=JSON.stringify(t);return e===void 0?"{}":e}catch{return"{}"}},k=t=>{if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}};export{m as WebMcpBridge};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@runtypelabs/persona",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.22.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",
|
|
@@ -129,7 +129,7 @@
|
|
|
129
129
|
"src"
|
|
130
130
|
],
|
|
131
131
|
"dependencies": {
|
|
132
|
-
"@mcp-b/webmcp-polyfill": "^
|
|
132
|
+
"@mcp-b/webmcp-polyfill": "^5.1.0",
|
|
133
133
|
"dompurify": "^3.4.13",
|
|
134
134
|
"idiomorph": "^0.7.4",
|
|
135
135
|
"lucide": "^1.18.0",
|
|
@@ -825,6 +825,137 @@ describe('controller wiring', () => {
|
|
|
825
825
|
mount.remove();
|
|
826
826
|
});
|
|
827
827
|
|
|
828
|
+
it('persists the latest durable cursor with the transcript before page exit', async () => {
|
|
829
|
+
await seedToken('cvt_stored');
|
|
830
|
+
installFetch([ok({ sessionId: 'sess_ui' })]);
|
|
831
|
+
const mount = document.createElement('div');
|
|
832
|
+
document.body.appendChild(mount);
|
|
833
|
+
const controller = createAgentExperience(mount, {
|
|
834
|
+
apiUrl: API_URL,
|
|
835
|
+
clientToken: CLIENT_TOKEN,
|
|
836
|
+
launcher: { enabled: false },
|
|
837
|
+
});
|
|
838
|
+
await vi.waitFor(() => expect(requests).toHaveLength(1));
|
|
839
|
+
|
|
840
|
+
let streamController!: ReadableStreamDefaultController<Uint8Array>;
|
|
841
|
+
const stream = new ReadableStream<Uint8Array>({
|
|
842
|
+
start(value) {
|
|
843
|
+
streamController = value;
|
|
844
|
+
},
|
|
845
|
+
});
|
|
846
|
+
const connected = controller.connectStream(stream);
|
|
847
|
+
const encoder = new TextEncoder();
|
|
848
|
+
streamController.enqueue(
|
|
849
|
+
encoder.encode(
|
|
850
|
+
'id: 7\nevent: text_delta\ndata: {"type":"text_delta","executionId":"exec_exit_latest","id":"text_exit_latest","delta":"Hi"}\n\n'
|
|
851
|
+
)
|
|
852
|
+
);
|
|
853
|
+
await vi.waitFor(() =>
|
|
854
|
+
expect(controller.getPersistentMetadata().durableResume).toEqual({
|
|
855
|
+
executionId: 'exec_exit_latest',
|
|
856
|
+
after: '7',
|
|
857
|
+
})
|
|
858
|
+
);
|
|
859
|
+
|
|
860
|
+
streamController.enqueue(
|
|
861
|
+
encoder.encode(
|
|
862
|
+
'id: 8\nevent: text_delta\ndata: {"type":"text_delta","executionId":"exec_exit_latest","id":"text_exit_latest","delta":" there"}\n\n'
|
|
863
|
+
)
|
|
864
|
+
);
|
|
865
|
+
await vi.waitFor(() =>
|
|
866
|
+
expect(controller.getMessages().find((message) => message.role === 'assistant')?.content).toBe(
|
|
867
|
+
'Hi there'
|
|
868
|
+
)
|
|
869
|
+
);
|
|
870
|
+
await vi.waitFor(() =>
|
|
871
|
+
expect(controller.getPersistentMetadata().durableResume).toEqual({
|
|
872
|
+
executionId: 'exec_exit_latest',
|
|
873
|
+
after: '8',
|
|
874
|
+
})
|
|
875
|
+
);
|
|
876
|
+
|
|
877
|
+
window.dispatchEvent(new Event('pagehide'));
|
|
878
|
+
|
|
879
|
+
streamController.close();
|
|
880
|
+
await connected;
|
|
881
|
+
controller.destroy();
|
|
882
|
+
mount.remove();
|
|
883
|
+
});
|
|
884
|
+
|
|
885
|
+
it('keeps async transcript snapshots aligned with the durable cursor', async () => {
|
|
886
|
+
await seedToken('cvt_stored');
|
|
887
|
+
installFetch([ok({ sessionId: 'sess_ui' })]);
|
|
888
|
+
const saves: AgentWidgetStoredState[] = [];
|
|
889
|
+
const mount = document.createElement('div');
|
|
890
|
+
document.body.appendChild(mount);
|
|
891
|
+
const controller = createAgentExperience(mount, {
|
|
892
|
+
apiUrl: API_URL,
|
|
893
|
+
clientToken: CLIENT_TOKEN,
|
|
894
|
+
launcher: { enabled: false },
|
|
895
|
+
storageAdapter: {
|
|
896
|
+
save: async (state) => {
|
|
897
|
+
await Promise.resolve();
|
|
898
|
+
saves.push(state);
|
|
899
|
+
},
|
|
900
|
+
},
|
|
901
|
+
});
|
|
902
|
+
await vi.waitFor(() => expect(requests).toHaveLength(1));
|
|
903
|
+
|
|
904
|
+
let streamController!: ReadableStreamDefaultController<Uint8Array>;
|
|
905
|
+
const stream = new ReadableStream<Uint8Array>({
|
|
906
|
+
start(value) {
|
|
907
|
+
streamController = value;
|
|
908
|
+
},
|
|
909
|
+
});
|
|
910
|
+
const connected = controller.connectStream(stream);
|
|
911
|
+
const encoder = new TextEncoder();
|
|
912
|
+
streamController.enqueue(
|
|
913
|
+
encoder.encode(
|
|
914
|
+
'id: 7\nevent: text_delta\ndata: {"type":"text_delta","executionId":"exec_async","id":"text_async","delta":"Hi"}\n\n'
|
|
915
|
+
)
|
|
916
|
+
);
|
|
917
|
+
await vi.waitFor(() =>
|
|
918
|
+
expect(controller.getPersistentMetadata().durableResume).toEqual({
|
|
919
|
+
executionId: 'exec_async',
|
|
920
|
+
after: '7',
|
|
921
|
+
})
|
|
922
|
+
);
|
|
923
|
+
|
|
924
|
+
streamController.enqueue(
|
|
925
|
+
encoder.encode(
|
|
926
|
+
'id: 8\nevent: text_delta\ndata: {"type":"text_delta","executionId":"exec_async","id":"text_async","delta":" there"}\n\n'
|
|
927
|
+
)
|
|
928
|
+
);
|
|
929
|
+
let firstCompleteTranscript: AgentWidgetStoredState | undefined;
|
|
930
|
+
await vi.waitFor(() => {
|
|
931
|
+
firstCompleteTranscript = saves.find((state) =>
|
|
932
|
+
state.messages?.some(
|
|
933
|
+
(message) => message.role === 'assistant' && message.content === 'Hi there'
|
|
934
|
+
)
|
|
935
|
+
);
|
|
936
|
+
expect(firstCompleteTranscript).toBeDefined();
|
|
937
|
+
});
|
|
938
|
+
expect(firstCompleteTranscript?.metadata?.durableResume).toEqual({
|
|
939
|
+
executionId: 'exec_async',
|
|
940
|
+
after: '8',
|
|
941
|
+
});
|
|
942
|
+
await Promise.resolve();
|
|
943
|
+
const savesBeforeExit = saves.length;
|
|
944
|
+
window.dispatchEvent(new Event('pagehide'));
|
|
945
|
+
await Promise.resolve();
|
|
946
|
+
expect(saves).toHaveLength(savesBeforeExit);
|
|
947
|
+
|
|
948
|
+
streamController.enqueue(
|
|
949
|
+
encoder.encode(
|
|
950
|
+
'id: 9\nevent: execution_complete\ndata: {"type":"execution_complete","executionId":"exec_async","kind":"agent","success":true}\n\n'
|
|
951
|
+
)
|
|
952
|
+
);
|
|
953
|
+
streamController.close();
|
|
954
|
+
await connected;
|
|
955
|
+
controller.destroy();
|
|
956
|
+
mount.remove();
|
|
957
|
+
});
|
|
958
|
+
|
|
828
959
|
it('uses Persona-owned stored recovery state to reopen the durable conversation', async () => {
|
|
829
960
|
await seedToken('cvt_stored');
|
|
830
961
|
global.fetch = vi.fn(async (url: string | URL | Request, options?: RequestInit) => {
|
|
@@ -447,6 +447,11 @@ function setupPreviewLoading(
|
|
|
447
447
|
const addTimer = (fn: () => void, ms: number): void => {
|
|
448
448
|
const id = setTimeout(() => {
|
|
449
449
|
timers.delete(id);
|
|
450
|
+
// Unit tests drop rendered blocks without running destroy(), so a
|
|
451
|
+
// pending timer can outlive the test file's DOM environment. Every
|
|
452
|
+
// callback here does DOM work; with no document left there is nothing
|
|
453
|
+
// to do (and `document.createElement` would throw).
|
|
454
|
+
if (typeof document === "undefined") return;
|
|
450
455
|
fn();
|
|
451
456
|
}, ms) as unknown as number;
|
|
452
457
|
timers.add(id);
|