@runtypelabs/persona 4.21.1 → 4.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/dist/animations/glyph-cycle.d.cts +1 -1
  2. package/dist/animations/glyph-cycle.d.ts +1 -1
  3. package/dist/animations/{types-B_JdVK9o.d.cts → types-9Vxm-PPz.d.cts} +136 -6
  4. package/dist/animations/{types-B_JdVK9o.d.ts → types-9Vxm-PPz.d.ts} +136 -6
  5. package/dist/animations/wipe.d.cts +1 -1
  6. package/dist/animations/wipe.d.ts +1 -1
  7. package/dist/animations-extra.d.cts +136 -6
  8. package/dist/animations-extra.d.ts +136 -6
  9. package/dist/{approval-ui-RNNBR5R3.js → approval-ui-K7R5Q5OC.js} +1 -1
  10. package/dist/approval-ui.cjs +2 -2
  11. package/dist/approval-ui.d.cts +221 -16
  12. package/dist/approval-ui.d.ts +221 -16
  13. package/dist/approval-ui.js +2 -2
  14. package/dist/artifacts-ui-F4N6VMKF.js +7 -0
  15. package/dist/artifacts-ui.cjs +1 -1
  16. package/dist/artifacts-ui.d.cts +221 -16
  17. package/dist/artifacts-ui.d.ts +221 -16
  18. package/dist/artifacts-ui.js +1 -1
  19. package/dist/chunk-NQLDCJAP.js +4 -0
  20. package/dist/codegen.cjs +1 -1
  21. package/dist/codegen.js +1 -1
  22. package/dist/context-mentions.d.cts +221 -16
  23. package/dist/context-mentions.d.ts +221 -16
  24. package/dist/event-stream-view-GL3ADRY2.js +1 -0
  25. package/dist/event-stream-view.cjs +1 -1
  26. package/dist/event-stream-view.d.cts +221 -16
  27. package/dist/event-stream-view.d.ts +221 -16
  28. package/dist/event-stream-view.js +1 -1
  29. package/dist/forms-ui.d.cts +234 -25
  30. package/dist/forms-ui.d.ts +234 -25
  31. package/dist/history-view.d.cts +136 -6
  32. package/dist/history-view.d.ts +136 -6
  33. package/dist/index.cjs +70 -70
  34. package/dist/index.cjs.map +1 -1
  35. package/dist/index.d.cts +302 -32
  36. package/dist/index.d.ts +302 -32
  37. package/dist/index.global.js +54 -54
  38. package/dist/index.global.js.map +1 -1
  39. package/dist/index.js +69 -69
  40. package/dist/index.js.map +1 -1
  41. package/dist/launcher.global.js +2 -2
  42. package/dist/launcher.global.js.map +1 -1
  43. package/dist/session-reconnect.d.cts +221 -16
  44. package/dist/session-reconnect.d.ts +221 -16
  45. package/dist/smart-dom-reader.d.cts +221 -16
  46. package/dist/smart-dom-reader.d.ts +221 -16
  47. package/dist/testing.cjs +3 -3
  48. package/dist/testing.d.cts +3 -4
  49. package/dist/testing.d.ts +3 -4
  50. package/dist/testing.js +3 -3
  51. package/dist/theme-editor-preview.cjs +73 -73
  52. package/dist/theme-editor-preview.d.cts +221 -16
  53. package/dist/theme-editor-preview.d.ts +221 -16
  54. package/dist/theme-editor-preview.js +51 -51
  55. package/dist/theme-editor.cjs +4 -4
  56. package/dist/theme-editor.d.cts +221 -16
  57. package/dist/theme-editor.d.ts +221 -16
  58. package/dist/theme-editor.js +2 -2
  59. package/dist/theme-reference.cjs +1 -1
  60. package/dist/theme-reference.d.cts +65 -1
  61. package/dist/theme-reference.d.ts +65 -1
  62. package/dist/theme-reference.js +1 -1
  63. package/dist/voice-runtime.d.cts +6 -2
  64. package/dist/voice-runtime.d.ts +6 -2
  65. package/dist/webmcp-polyfill.js +1 -4
  66. package/dist/webmcp-runtime-JI7T4QYF.js +6 -0
  67. package/dist/webmcp-runtime.cjs +2 -2
  68. package/dist/webmcp-runtime.d.cts +34 -2
  69. package/dist/webmcp-runtime.d.ts +34 -2
  70. package/dist/webmcp-runtime.js +2 -2
  71. package/package.json +2 -2
  72. package/src/ask-user-question-tool.ts +1 -1
  73. package/src/client-history-rest.test.ts +2 -1
  74. package/src/client-visitor-history.test.ts +20 -4
  75. package/src/client.composer-options.test.ts +1 -1
  76. package/src/client.interrupt.test.ts +2 -2
  77. package/src/client.test.ts +477 -915
  78. package/src/client.ts +134 -494
  79. package/src/client.unified-tools.test.ts +76 -0
  80. package/src/components/artifact-preview.ts +5 -0
  81. package/src/components/event-stream-badge-theming.test.ts +162 -0
  82. package/src/components/event-stream-view.test.ts +76 -76
  83. package/src/components/event-stream-view.ts +55 -20
  84. package/src/components/tool-bubble.test.ts +12 -0
  85. package/src/components/tool-bubble.ts +13 -2
  86. package/src/event-stream-view-bundle.test.ts +2 -2
  87. package/src/generated/runtype-openapi-contract.ts +137 -1
  88. package/src/index-core.ts +2 -0
  89. package/src/internal/runtype-history-provider.test.ts +2 -2
  90. package/src/runtime/init.registry.test.ts +56 -0
  91. package/src/runtime/init.ts +17 -0
  92. package/src/session-history.test.ts +1 -1
  93. package/src/session.quote.test.ts +1 -1
  94. package/src/session.resubmit-from.test.ts +1 -1
  95. package/src/session.test.ts +5 -5
  96. package/src/session.ts +95 -36
  97. package/src/suggest-replies-tool.ts +1 -1
  98. package/src/testing/mock-stream.test.ts +37 -16
  99. package/src/testing/mock-stream.ts +14 -9
  100. package/src/types/theme.ts +41 -1
  101. package/src/types.ts +57 -15
  102. package/src/ui.ask-user-question-plugin.test.ts +7 -7
  103. package/src/ui.composer-defer-one.test.ts +6 -34
  104. package/src/ui.composer-draft-persistence.test.ts +1 -1
  105. package/src/ui.composer-quote.test.ts +1 -1
  106. package/src/ui.message-history-actions.test.ts +1 -1
  107. package/src/ui.reasoning-display.test.ts +136 -2
  108. package/src/ui.streaming-coalescing.test.ts +10 -13
  109. package/src/ui.ts +101 -35
  110. package/src/ui.typing-indicator.test.ts +216 -0
  111. package/src/ui.voice-custom-provider.test.ts +211 -0
  112. package/src/utils/__snapshots__/tokens-parity.test.ts.snap +1740 -0
  113. package/src/utils/event-stream-buffer.test.ts +13 -13
  114. package/src/utils/event-stream-capture.test.ts +20 -20
  115. package/src/utils/formatting.ts +22 -0
  116. package/src/utils/theme.ts +16 -0
  117. package/src/utils/throughput-tracker.test.ts +100 -142
  118. package/src/utils/throughput-tracker.ts +18 -132
  119. package/src/utils/tokens.ts +59 -0
  120. package/src/utils/voice-support.ts +18 -1
  121. package/src/voice/voice-turn-tracker.ts +18 -0
  122. package/src/webmcp-bridge.test.ts +132 -23
  123. package/src/webmcp-bridge.ts +27 -3
  124. package/src/webmcp-runtime-entry.ts +71 -11
  125. package/dist/artifacts-ui-J6AKUGTS.js +0 -7
  126. package/dist/chunk-HBE7LFNT.js +0 -4
  127. package/dist/event-stream-view-73NWKWVQ.js +0 -1
  128. package/dist/webmcp-runtime-P3CHZRHF.js +0 -6
  129. package/src/utils/__fixtures__/unified-translator.oracle.ts +0 -717
@@ -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&&gt(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};
@@ -1,6 +1,6 @@
1
- "use strict";var m=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var W=(t,e)=>{for(var n in e)m(t,n,{get:e[n],enumerable:!0})},P=(t,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of w(e))!T.call(t,r)&&r!==n&&m(t,r,{get:()=>e[r],enumerable:!(o=x(e,r))||o.enumerable});return t};var v=t=>P(m({},"__esModule",{value:!0}),t);var I={};W(I,{WebMcpBridge:()=>u});module.exports=v(I);var h="webmcp:",A=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)}},u=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 s={name:r.name,description:r.description,origin:"webmcp",...o?{pageOrigin:o}:{}},a=D(r.inputSchema);return a&&(s.parametersSchema=a),s})}async executeToolCall(e,n,o){if(await this.ensureReady(),this.config.enabled!==!0)return l("WebMCP is not enabled on this widget.");let r=this.getModelContext();if(!r){let i=typeof document<"u"&&!!document.modelContext;return l(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 s=A(e),a;try{a=await r.getTools()}catch(i){let p=i instanceof Error?i.message:String(i);return l(`Failed to read WebMCP registry: ${p}`)}this.deps.recordToolDisplayTitles(a);let f=a.find(i=>i.name===s);if(!f)return l(`WebMCP tool not registered on this page: ${s}`);if(!this.passesClientAllowlist(s))return l(`WebMCP tool not allowed by client allowlist: ${s}`);if(o?.aborted)return l("Aborted by cancel()");let b=this.deps.getToolDisplayTitle(s),C={toolName:s,args:n,description:f.description,...b?{title:b}:{},reason:"gate"};if(!await this.requestConfirm(C))return l("User declined the tool call.");if(o?.aborted)return l("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 i=await r.executeTool(f,$(n),{signal:c.signal});return O(i)}catch(i){if(y)return l(`WebMCP tool '${s}' timed out after ${this.timeoutMs}ms`);if(o?.aborted)return l("Aborted by cancel()");let p=i instanceof Error?i.message:String(i);return l(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??k;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=>S(e,o))}},S=(t,e)=>{if(e==="*")return!0;let n=e.replace(/[.+?^${}()|[\]\\]/g,"\\$&");return new RegExp("^"+n.replace(/\*/g,".*")+"$").test(t)},D=t=>{if(!(t===void 0||t===""))try{let e=JSON.parse(t);return e!==null&&typeof e=="object"?e:void 0}catch{return}},O=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(e)}]}},l=t=>({isError:!0,content:[{type:"text",text:t}]}),k=async t=>{if(typeof window>"u"||typeof window.confirm!="function")return!1;let e=R(t.args),n=`Allow the AI to call ${t.toolName}`+(e?`
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)},R=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)}},$=t=>{if(t===void 0)return"{}";try{let e=JSON.stringify(t);return e===void 0?"{}":e}catch{return"{}"}},E=t=>{if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}};0&&(module.exports={WebMcpBridge});
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
- /** JSON-encoded JSON Schema for the tool's input. */
179
- inputSchema?: string;
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 = {
@@ -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
- /** JSON-encoded JSON Schema for the tool's input. */
179
- inputSchema?: string;
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 = {
@@ -1,6 +1,6 @@
1
- var g="webmcp:",M=t=>t.startsWith(g)?t.slice(g.length):t,d={warn(t,...e){typeof console<"u"&&typeof console.warn=="function"&&console.warn(`[Persona/WebMCP] ${t}`,...e)}},p=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 s={name:i.name,description:i.description,origin:"webmcp",...o?{pageOrigin:o}:{}},a=w(i.inputSchema);return a&&(s.parametersSchema=a),s})}async executeToolCall(e,n,o){if(await this.ensureReady(),this.config.enabled!==!0)return l("WebMCP is not enabled on this widget.");let i=this.getModelContext();if(!i){let r=typeof document<"u"&&!!document.modelContext;return l(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 s=M(e),a;try{a=await i.getTools()}catch(r){let f=r instanceof Error?r.message:String(r);return l(`Failed to read WebMCP registry: ${f}`)}this.deps.recordToolDisplayTitles(a);let u=a.find(r=>r.name===s);if(!u)return l(`WebMCP tool not registered on this page: ${s}`);if(!this.passesClientAllowlist(s))return l(`WebMCP tool not allowed by client allowlist: ${s}`);if(o?.aborted)return l("Aborted by cancel()");let m=this.deps.getToolDisplayTitle(s),h={toolName:s,args:n,description:u.description,...m?{title:m}:{},reason:"gate"};if(!await this.requestConfirm(h))return l("User declined the tool call.");if(o?.aborted)return l("Aborted by cancel()");let c=new AbortController,b=!1,C=setTimeout(()=>{b=!0,c.abort()},this.timeoutMs),y=()=>c.abort();o&&(o.aborted?c.abort():o.addEventListener("abort",y,{once:!0}));try{let r=await i.executeTool(u,v(n),{signal:c.signal});return T(r)}catch(r){if(b)return l(`WebMCP tool '${s}' timed out after ${this.timeoutMs}ms`);if(o?.aborted)return l("Aborted by cancel()");let f=r instanceof Error?r.message:String(r);return l(f)}finally{clearTimeout(C),o&&o.removeEventListener("abort",y)}}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??W;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)},w=t=>{if(!(t===void 0||t===""))try{let e=JSON.parse(t);return e!==null&&typeof e=="object"?e:void 0}catch{return}},T=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:A(e)}]}},l=t=>({isError:!0,content:[{type:"text",text:t}]}),W=async t=>{if(typeof window>"u"||typeof window.confirm!="function")return!1;let e=P(t.args),n=`Allow the AI to call ${t.toolName}`+(e?`
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)},P=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)}},v=t=>{if(t===void 0)return"{}";try{let e=JSON.stringify(t);return e===void 0?"{}":e}catch{return"{}"}},A=t=>{if(t===void 0)return"";try{return JSON.stringify(t)}catch{return String(t)}};export{p as WebMcpBridge};
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.21.1",
3
+ "version": "4.22.1",
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": "^4.0.0",
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",
@@ -5,7 +5,7 @@
5
5
  * `clientTools[]` (set `features.askUserQuestion.expose: true`): the same
6
6
  * wire surface WebMCP page tools ride. The server registers it as a LOCAL
7
7
  * tool under its bare name (`origin: 'sdk'` tools are not `webmcp:`-prefixed),
8
- * so when the model calls it the execution pauses with a `step_await`, the
8
+ * so when the model calls it the execution pauses with an `await`, the
9
9
  * widget's answer-pill sheet renders, and `session.resolveAskUserQuestion()`
10
10
  * resumes the execution with the structured answers. The public await frame
11
11
  * for a local-tool pause carries no `awaitReason`; that discriminator is
@@ -197,6 +197,7 @@ describe('history REST - request shape', () => {
197
197
  id: 'conv_1',
198
198
  title: 'Placeholder title',
199
199
  flowId: 'flow_1',
200
+ targetId: 'flow_1',
200
201
  messageCount: 4,
201
202
  createdAt: '2026-08-01T00:00:00.000Z',
202
203
  updatedAt: '2026-08-02T00:00:00.000Z',
@@ -222,7 +223,7 @@ describe('history REST - request shape', () => {
222
223
  expect(requests[1].method).toBe('GET');
223
224
  expect(requests[1].headers['X-Visitor-Token']).toBe('cvt_stored');
224
225
  expect(requests[1].headers['X-Persona-Version']).toBeTruthy();
225
- // Deprecated flowId is consumed at this boundary and never re-exposed.
226
+ // The deprecated flowId alias is not re-exposed.
226
227
  expect(page.data[0]).toEqual({
227
228
  id: 'conv_1',
228
229
  title: 'Placeholder title',
@@ -203,7 +203,7 @@ describe('client visitor history - init capability shape', () => {
203
203
  expect(requests[0].body).not.toHaveProperty('conversationId');
204
204
  });
205
205
 
206
- it('normalizes targetId, preferring the top-level field over flow.id', async () => {
206
+ it('uses canonical targetId without falling back to flow metadata', async () => {
207
207
  installFetch([
208
208
  ok({ targetId: 'agent_9' }),
209
209
  ok({ sessionId: 'sess_2', targetId: undefined, flow: { id: 'flow_7', name: 'F', description: null } }),
@@ -216,7 +216,23 @@ describe('client visitor history - init capability shape', () => {
216
216
 
217
217
  expect(a.targetId).toBe('agent_9');
218
218
  expect(a.flow.id).toBe('flow_1');
219
- expect(b.targetId).toBe('flow_7');
219
+ expect(b.targetId).toBeUndefined();
220
+ });
221
+
222
+ it('surfaces an init 400 without retrying a different payload', async () => {
223
+ installFetch([fail(400, { error: 'invalid_token' })]);
224
+ await expect(makeClient({}).client.initSession()).rejects.toThrow('invalid_token');
225
+ expect(requests).toHaveLength(1);
226
+ expect(requests[0].body.durableRecovery).toBe(true);
227
+ });
228
+
229
+ it('accepts a data-only init with no flow or target metadata', async () => {
230
+ installFetch([() => ({ ok: true, status: 200, json: async () => ({
231
+ ...initBody(), flow: undefined, targetId: undefined, app: { id: 'app_1' },
232
+ }) })]);
233
+ const session = await makeClient({}).client.initSession();
234
+ expect(session.targetId).toBeUndefined();
235
+ expect(session.conversationId).toBe('conv_1');
220
236
  });
221
237
 
222
238
  it('uses the exact visitor credential and durable cursor for reconnect', async () => {
@@ -235,14 +251,14 @@ describe('client visitor history - init capability shape', () => {
235
251
  const controller = new AbortController();
236
252
  const response = await h.client.reconnectClientTokenStream({
237
253
  executionId: 'exec_7',
238
- after: '12',
254
+ after: '12.3',
239
255
  signal: controller.signal,
240
256
  });
241
257
 
242
258
  expect(response).toBe(events);
243
259
  expect(fetchMock.mock.calls[1]?.[0]).toBe(
244
260
  `${API_URL}/v1/client/conversations/conv_1/executions/exec_7/events` +
245
- '?sessionId=sess_1&after=12'
261
+ '?sessionId=sess_1&after=12.3'
246
262
  );
247
263
  expect(fetchMock.mock.calls[1]?.[1]).toMatchObject({
248
264
  method: 'GET',
@@ -22,7 +22,7 @@ const streamResponse = () => {
22
22
  body: new ReadableStream({
23
23
  start(controller) {
24
24
  controller.enqueue(
25
- encoder.encode('data: {"type":"flow_complete","success":true}\n\n')
25
+ encoder.encode('data: {"type":"execution_complete","success":true}\n\n')
26
26
  );
27
27
  controller.close();
28
28
  },
@@ -120,9 +120,9 @@ describe("client-token turn identity", () => {
120
120
  await vi.waitFor(() => expect(index).toBe(2));
121
121
 
122
122
  const beforeCount = firstEvents.length;
123
- first.push('data: {"type":"flow_complete","success":true}\n\n');
123
+ first.push('data: {"type":"execution_complete","success":true}\n\n');
124
124
  first.close();
125
- second.push('data: {"type":"flow_complete","success":true}\n\n');
125
+ second.push('data: {"type":"execution_complete","success":true}\n\n');
126
126
  second.close();
127
127
  await Promise.all([firstDispatch, secondDispatch]);
128
128