From b129f8246e536ccd4e45b6442e48c2d3c52c9985 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Wed, 19 Jul 2023 14:55:11 -0700 Subject: [PATCH 001/582] Removing python from CodeQL Analysis. (#10) * Removing python from CodeQL Analysis. * Updating .gitignore. * removing files that dhould be ignored. * Fixing .gitignore. * Fixing yarn.lock. --------- Co-authored-by: Ben Thomas --- .github/workflows/codeql-analysis.yml | 2 +- .gitignore | 4 +- webapp/package.json | 7 +- webapp/yarn.lock | 1865 ++++++++++++------------- 4 files changed, 927 insertions(+), 951 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 6ae3a7a79..a360ada33 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'csharp', 'python' ] + language: [ 'csharp' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] # Use only 'java' to analyze code written in Java, Kotlin or both # Use only 'javascript' to analyze code written in JavaScript, TypeScript or both diff --git a/.gitignore b/.gitignore index 530b14105..81cd9e2d7 100644 --- a/.gitignore +++ b/.gitignore @@ -476,5 +476,5 @@ playwright-report/ # Static Web App deployment config swa-cli.config.json -**/copilot-chat-app/webapp/build -**/copilot-chat-app/webapp/node_modules \ No newline at end of file +webapp/build/ +webapp/node_modules/ \ No newline at end of file diff --git a/webapp/package.json b/webapp/package.json index d983bb43c..e7b833af5 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -35,11 +35,11 @@ "strict-event-emitter-types": "^2.0.0" }, "devDependencies": { + "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@types/debug": "^4.1.7", "@types/node": "^18.11.9", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", - "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "better-vsts-npm-auth": "^7.0.0", "depcheck": "^1.4.3", "eslint": "^8.42.0", @@ -54,7 +54,7 @@ "extends": [ "react-app", "react-app/jest", - "../../.eslintrc.js" + "../.eslintrc.js" ] }, "browserslist": { @@ -69,5 +69,6 @@ "last 1 firefox version", "last 1 safari version" ] - } + }, + "packageManager": "yarn@1.22.19" } diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 435996e18..f76d4f561 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -2,6 +2,11 @@ # yarn lockfile v1 +"@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + "@alloc/quick-lru@^5.2.0": version "5.2.0" resolved "https://registry.yarnpkg.com/@alloc/quick-lru/-/quick-lru-5.2.0.tgz#7bf68b20c0a350f936915fcae06f58e32007ce30" @@ -40,36 +45,35 @@ tslib "^2.2.0" "@azure/ms-rest-js@^2.6.4": - version "2.6.6" - resolved "https://registry.yarnpkg.com/@azure/ms-rest-js/-/ms-rest-js-2.6.6.tgz#a2ae4a515565ae1b73729b52b25875853bb3240a" - integrity sha512-WYIda8VvrkZE68xHgOxUXvjThxNf1nnGPPe0rAljqK5HJHIZ12Pi3YhEDOn3Ge7UnwaaM3eFO0VtAy4nGVI27Q== + version "2.7.0" + resolved "https://registry.yarnpkg.com/@azure/ms-rest-js/-/ms-rest-js-2.7.0.tgz#8639065577ffdf4946951e1d246334ebfd72d537" + integrity sha512-ngbzWbqF+NmztDOpLBVDxYM+XLcUj7nKhxGbSU9WtIsXfRB//cf2ZbAG5HkOrhU9/wd/ORRB6lM/d69RKVjiyA== dependencies: "@azure/core-auth" "^1.1.4" abort-controller "^3.0.0" form-data "^2.5.0" node-fetch "^2.6.7" - tough-cookie "^3.0.1" tslib "^1.10.0" tunnel "0.0.6" uuid "^8.3.2" xml2js "^0.5.0" "@azure/msal-browser@^2.32.1": - version "2.37.1" - resolved "https://registry.yarnpkg.com/@azure/msal-browser/-/msal-browser-2.37.1.tgz#7e3fa7df9c6e74eb1fb640e73ef3b5b4407ee98d" - integrity sha512-EoKQISEpIY39Ru1OpWkeFZBcwp6Y0bG81bVmdyy4QJebPPDdVzfm62PSU0XFIRc3bqjZ4PBKBLMYLuo9NZYAow== + version "2.38.0" + resolved "https://registry.yarnpkg.com/@azure/msal-browser/-/msal-browser-2.38.0.tgz#c3621dc4cc9bf8c5589ec3e4474a63d6985ebd6b" + integrity sha512-gxBh83IumHgEP9uMCm9pJLKLRwICMQTxG9TX3AytdNt3oLUI3tytm/szYD5u5zKJgSkhHvwFSM+NPnM04hYw3w== dependencies: - "@azure/msal-common" "13.1.0" + "@azure/msal-common" "13.2.0" -"@azure/msal-common@13.1.0": - version "13.1.0" - resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-13.1.0.tgz#73a787ec1e7880c30b187cf451404af547d95339" - integrity sha512-wj+ULrRB0HTuMmtrMjg8j3guCx32GE2BCPbsMCZkHgL1BZetC3o/Su5UJEQMX1HNc9CrIaQNx5WaKWHygYDe0g== +"@azure/msal-common@13.2.0": + version "13.2.0" + resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-13.2.0.tgz#e3c6e35c0bf96ea59deaab08286a7b51b9d1ec91" + integrity sha512-rnstQ7Zgn3fSTKNQO+/YNV34/QXJs0vni7IA0/3QB1EEyrJg14xyRmTqlw9ta+pdSuT5OJwUP8kI3D/rBwUIBw== "@azure/msal-react@^1.5.1": - version "1.5.8" - resolved "https://registry.yarnpkg.com/@azure/msal-react/-/msal-react-1.5.8.tgz#7759814559d9e4c5524d8a921229fb3eba7d4af2" - integrity sha512-6lkNjF7WHOFUOKInsHUT5RQGEK9s9KtxSKZxhQPpvYrQrpp6/W3CMp+TkxgeFylQZk3iwUO79yf5cw/Z71I3vQ== + version "1.5.9" + resolved "https://registry.yarnpkg.com/@azure/msal-react/-/msal-react-1.5.9.tgz#8a7c941deabe7bf365204ada1711146846c64825" + integrity sha512-OqlBmo3h2ucp+OtpXwjNcKaUdIwRMUoEcixZz9rKzHJJ8VR7rngy2pHf+4tCTqwQXQOsRKdneNKG3Osh/AAhzg== "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.22.5", "@babel/code-frame@^7.8.3": version "7.22.5" @@ -78,45 +82,45 @@ dependencies: "@babel/highlight" "^7.22.5" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.5.tgz#b1f6c86a02d85d2dd3368a2b67c09add8cd0c255" - integrity sha512-4Jc/YuIaYqKnDDz892kPIledykKg12Aw1PYX5i/TY28anJtacvM1Rrr8wbieB9GfEJwlzqT0hUEao0CxEebiDA== +"@babel/compat-data@^7.22.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.22.9.tgz#71cdb00a1ce3a329ce4cbec3a44f9fef35669730" + integrity sha512-5UamI7xkUcJ3i9qVDS+KFDEK8/7oJ55/sJMB1Ge7IEapr7KfdfV/HErR+koZwOfd+SgtFKOKRhRakdg++DcJpQ== "@babel/core@^7.1.0", "@babel/core@^7.11.1", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.7.2", "@babel/core@^7.8.0": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.5.tgz#d67d9747ecf26ee7ecd3ebae1ee22225fe902a89" - integrity sha512-SBuTAjg91A3eKOvD+bPEz3LlhHZRNu1nFOVts9lzDJTXshHTjII0BAtDS3Y2DAkdZdDKWVZGVwkDfc4Clxn1dg== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.22.9.tgz#bd96492c68822198f33e8a256061da3cf391f58f" + integrity sha512-G2EgeufBcYw27U4hhoIwFcgc1XU7TlXJ3mv04oOv1WCuo900U/anZSPzEqNjwdjgffkk2Gs0AN0dW1CKVLcG7w== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.5" - "@babel/helper-compilation-targets" "^7.22.5" - "@babel/helper-module-transforms" "^7.22.5" - "@babel/helpers" "^7.22.5" - "@babel/parser" "^7.22.5" + "@babel/generator" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" + "@babel/helper-module-transforms" "^7.22.9" + "@babel/helpers" "^7.22.6" + "@babel/parser" "^7.22.7" "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" + "@babel/traverse" "^7.22.8" "@babel/types" "^7.22.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.2" - semver "^6.3.0" + semver "^6.3.1" "@babel/eslint-parser@^7.16.3": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.22.5.tgz#fa032503b9e2d188e25b1b95d29e8b8431042d78" - integrity sha512-C69RWYNYtrgIRE5CmTd77ZiLDXqgBipahJc/jHP3sLcAGj6AJzxNIuKNpVnICqbyK7X3pFUfEvL++rvtbQpZkQ== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.22.9.tgz#75f8aa978d1e76c87cc6f26c1ea16ae58804d390" + integrity sha512-xdMkt39/nviO/4vpVdrEYPwXCsYIXSSAr6mC7WQsNIlGnuxKyKE7GZjalcnbSWiC4OXGNNN3UQPeHfjSC6sTDA== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" - semver "^6.3.0" + semver "^6.3.1" -"@babel/generator@^7.22.5", "@babel/generator@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.5.tgz#1e7bf768688acfb05cf30b2369ef855e82d984f7" - integrity sha512-+lcUbnTRhd0jOewtFSedLyiPsD5tswKkbgcezOqqWFUVNEwoUTlpPOBmvhG7OXWLR4jMdv0czPGH5XbflnD1EA== +"@babel/generator@^7.22.7", "@babel/generator@^7.22.9", "@babel/generator@^7.7.2": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.22.9.tgz#572ecfa7a31002fa1de2a9d91621fd895da8493d" + integrity sha512-KtLMbmicyuK2Ak/FTCJVbDnkN1SlT8/kceFTiuDiiRUUSMnHMidxSCdG4ndkTOHHpoomWe/4xkvHkEOncwjYIw== dependencies: "@babel/types" "^7.22.5" "@jridgewell/gen-mapping" "^0.3.2" @@ -137,33 +141,18 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.5.tgz#fc7319fc54c5e2fa14b2909cf3c5fd3046813e02" - integrity sha512-Ji+ywpHeuqxB8WDxraCiqR0xfhYjiDE/e6k7FuIaANnoOFxAHskHChz4vA1mJC9Lbm01s1PVAGhQY4FUKSkGZw== +"@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.9.tgz#f9d0a7aaaa7cd32a3f31c9316a69f5a9bcacb892" + integrity sha512-7qYrNM6HjpnPHJbopxmb8hSPoZ0gsX8IvUS32JGVoy+pU9e5N0nLr1VjJoR6kA4d9dmGLxNYOjeB8sUDal2WMw== dependencies: - "@babel/compat-data" "^7.22.5" + "@babel/compat-data" "^7.22.9" "@babel/helper-validator-option" "^7.22.5" - browserslist "^4.21.3" + browserslist "^4.21.9" lru-cache "^5.1.1" - semver "^6.3.0" - -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.5.tgz#2192a1970ece4685fbff85b48da2c32fcb130b7c" - integrity sha512-xkb58MyOYIslxu3gKmVXmjTtUPvBU4odYzbiIQbWwLKIHCsx6UGZGX6F1IznMFVnDdirseUZopzN+ZRt8Xb33Q== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-member-expression-to-functions" "^7.22.5" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" - semver "^6.3.0" + semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.21.0": +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.5", "@babel/helper-create-class-features-plugin@^7.22.6", "@babel/helper-create-class-features-plugin@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.9.tgz#c36ea240bb3348f942f08b0fbe28d6d979fab236" integrity sha512-Pwyi89uO4YrGKxL/eNJ8lfEH55DnRloGPOseaA8NFNL6jAUnn+KccaISiFazCj5IolPPDjGSdzQzXVzODVRqUQ== @@ -179,25 +168,24 @@ semver "^6.3.1" "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.5.tgz#bb2bf0debfe39b831986a4efbf4066586819c6e4" - integrity sha512-1VpEFOIbMRaXyDeUwUfmTIxExLwQ+zkW+Bh5zXpApA3oQedBx9v/updixWxnx/bZpKw7u8VxWjb/qWpIcmPq8A== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.9.tgz#9d8e61a8d9366fe66198f57c40565663de0825f6" + integrity sha512-+svjVa/tFwsNSG4NEy1h85+HQ5imbT92Q5/bgtS7P0GTQlP8WuFdqsiABmQouhiFGyV66oGxZFpeYHza1rNsKw== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" regexpu-core "^5.3.1" - semver "^6.3.0" + semver "^6.3.1" -"@babel/helper-define-polyfill-provider@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.0.tgz#487053f103110f25b9755c5980e031e93ced24d8" - integrity sha512-RnanLx5ETe6aybRi1cO/edaRH+bNYWaryCEmjDDYyNr4wnSzyOp8T0dWipmqVHKEY3AbVKUom50AKSlj1zmKbg== +"@babel/helper-define-polyfill-provider@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.1.tgz#af1429c4a83ac316a6a8c2cc8ff45cb5d2998d3a" + integrity sha512-kX4oXixDxG197yhX+J3Wp+NpL2wuCFjWQAr6yX2jtCnflK9ulMI51ULFGIrWiX1jGfvAxdHp+XQCcP2bZGPs9A== dependencies: - "@babel/helper-compilation-targets" "^7.17.7" - "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-compilation-targets" "^7.22.6" + "@babel/helper-plugin-utils" "^7.22.5" debug "^4.1.1" lodash.debounce "^4.0.8" resolve "^1.14.2" - semver "^6.1.2" "@babel/helper-environment-visitor@^7.22.5": version "7.22.5" @@ -233,19 +221,16 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-module-transforms@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.5.tgz#0f65daa0716961b6e96b164034e737f60a80d2ef" - integrity sha512-+hGKDt/Ze8GFExiVHno/2dvG5IdstpzCq0y4Qc9OJ25D4q3pKfiIP/4Vp3/JvhDkLKsDK2api3q3fpIgiIF5bw== +"@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.22.9.tgz#92dfcb1fbbb2bc62529024f72d942a8c97142129" + integrity sha512-t+WA2Xn5K+rTeGtC8jCsdAH52bjggG5TKRuRrAGNM/mjIbO4GxvlLMFOEz9wXY5I2XQ60PMFsAG2WIcG82dQMQ== dependencies: "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-module-imports" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" "@babel/helper-validator-identifier" "^7.22.5" - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" - "@babel/types" "^7.22.5" "@babel/helper-optimise-call-expression@^7.22.5": version "7.22.5" @@ -254,34 +239,21 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.16.7", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.22.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== "@babel/helper-remap-async-to-generator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.5.tgz#14a38141a7bf2165ad38da61d61cf27b43015da2" - integrity sha512-cU0Sq1Rf4Z55fgz7haOakIyM7+x/uCFwXpLPaeRzfoUtAEAuUZjZvFPjL/rk5rW693dIgn2hng1W7xbT7lWT4g== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.9.tgz#53a25b7484e722d7efb9c350c75c032d4628de82" + integrity sha512-8WWC4oR4Px+tr+Fp0X3RHDVfINGpF3ad1HIbrc8A77epiR6eMMc6jsgozkzT2uDiOOdoS9cLIQ+XD2XvI2WSmQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-wrap-function" "^7.22.5" - "@babel/types" "^7.22.5" - -"@babel/helper-replace-supers@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.5.tgz#71bc5fb348856dea9fdc4eafd7e2e49f585145dc" - integrity sha512-aLdNM5I3kdI/V9xGNyKSF3X/gTyMUBohTZ+/3QdQKAA9vxIiy12E+8E2HoOP1/DjeqU+g6as35QHJNMDDYpuCg== - dependencies: - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-member-expression-to-functions" "^7.22.5" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" - "@babel/types" "^7.22.5" + "@babel/helper-wrap-function" "^7.22.9" -"@babel/helper-replace-supers@^7.22.9": +"@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": version "7.22.9" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.9.tgz#cbdc27d6d8d18cd22c81ae4293765a5d9afd0779" integrity sha512-LJIKvvpgPOPUThdYqcX6IXRuIcTkcAub0IaDRGCZH0p5GPUp7PhRU9QVgFcDDd51BaPkk77ZjqFwh6DZTAEmGg== @@ -304,13 +276,6 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-split-export-declaration@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.5.tgz#88cf11050edb95ed08d596f7a044462189127a08" - integrity sha512-thqK5QFghPKWLhAV321lxF95yCg2K3Ob5yw+M3VHWfdia0IkPXUtoLH8x/6Fh486QUvzhb8YOWHChTVen2/PoQ== - dependencies: - "@babel/types" "^7.22.5" - "@babel/helper-split-export-declaration@^7.22.6": version "7.22.6" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" @@ -333,23 +298,22 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.5.tgz#de52000a15a177413c8234fa3a8af4ee8102d0ac" integrity sha512-R3oB6xlIVKUnxNUxbmgq7pKjxpru24zlimpE8WK47fACIlM0II/Hm1RS8IaOI7NgCr6LNS+jl5l75m20npAziw== -"@babel/helper-wrap-function@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.5.tgz#44d205af19ed8d872b4eefb0d2fa65f45eb34f06" - integrity sha512-bYqLIBSEshYcYQyfks8ewYA8S30yaGSeRslcvKMvoUk6HHPySbxHq9YRi6ghhzEU+yhQv9bP/jXnygkStOcqZw== +"@babel/helper-wrap-function@^7.22.9": + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.9.tgz#189937248c45b0182c1dcf32f3444ca153944cb9" + integrity sha512-sZ+QzfauuUEfxSEjKFmi3qDSHgLsTPK/pEpoD/qonZKOtTPTLbf59oabPQ4rKekt9lFcj/hTZaOhWwFYrgjk+Q== dependencies: "@babel/helper-function-name" "^7.22.5" "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/helpers@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.5.tgz#74bb4373eb390d1ceed74a15ef97767e63120820" - integrity sha512-pSXRmfE1vzcUIDFQcSGA5Mr+GxBV9oiRKDuDxXvWQQBCh8HoIjs/2DlDB7H8smac1IVrB9/xdXj2N3Wol9Cr+Q== +"@babel/helpers@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.22.6.tgz#8e61d3395a4f0c5a8060f309fb008200969b5ecd" + integrity sha512-YjDs6y/fVOYFV8hAf1rxd1QvR9wJe1pDBZ2AREKq/SDayfPzgk0PBnVuTCE5X1acEpMMNOVUqoe+OwiZGJ+OaA== dependencies: "@babel/template" "^7.22.5" - "@babel/traverse" "^7.22.5" + "@babel/traverse" "^7.22.6" "@babel/types" "^7.22.5" "@babel/highlight@^7.22.5": @@ -366,10 +330,10 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e" integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng== -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.15", "@babel/parser@^7.20.7", "@babel/parser@^7.21.3", "@babel/parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.5.tgz#721fd042f3ce1896238cf1b341c77eb7dee7dbea" - integrity sha512-DFZMC9LJUG9PLOclRC32G63UXwzqS2koQC8dkx+PLdmt1xSePYpbT/NbsrJy8Q/muXz7o/h/d4A7Fuyixm559Q== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.15", "@babel/parser@^7.20.7", "@babel/parser@^7.21.3", "@babel/parser@^7.22.5", "@babel/parser@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.22.7.tgz#df8cf085ce92ddbdbf668a7f186ce848c9036cae" + integrity sha512-7NF8pOkHP5o2vpmGgNGcfAeCvOYhGLyA3Z4eBQkT1RJlWu47n63bCs93QfJ2hIAFCil7L5P2IWhs1oToVgrL0Q== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.5": version "7.22.5" @@ -396,14 +360,14 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-decorators@^7.16.4": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.22.5.tgz#dc8cdda048e5aea947efda920e030199806b868d" - integrity sha512-h8hlezQ4dl6ixodgXkH8lUfcD7x+WAuIqPUjwGoItynrXOAv4a4Tci1zA/qjzQjjcl0v3QpLdc2LM6ZACQuY7A== + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.22.7.tgz#9b5b73c2e404f0869ef8a8a53765f8203c5467a7" + integrity sha512-omXqPF7Onq4Bb7wHxXjM3jSMSJvUUbvDvmmds7KI5n9Cq6Ln5I05I1W2nRlRof1rGdiUxJrxwe285WF96XlBXQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.6" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-replace-supers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" "@babel/plugin-syntax-decorators" "^7.22.5" "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.0": @@ -631,10 +595,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-async-generator-functions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.5.tgz#7336356d23380eda9a56314974f053a020dab0c3" - integrity sha512-gGOEvFzm3fWoyD5uZq7vVTD57pPJ3PczPUD/xCFGjzBpUosnklmXyKnGQbbbGs1NPNPskFex0j93yKbHt0cHyg== +"@babel/plugin-transform-async-generator-functions@^7.22.7": + version "7.22.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.22.7.tgz#053e76c0a903b72b573cb1ab7d6882174d460a1b" + integrity sha512-7HmE7pk/Fmke45TODvxvkxRMV9RazV+ZZzhOL9AG8G29TLrr3jkjwF7uJfxZ30EoXpO+LJkq4oA8NjO2DTnEDg== dependencies: "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" @@ -681,19 +645,19 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-transform-classes@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.5.tgz#635d4e98da741fad814984639f4c0149eb0135e1" - integrity sha512-2edQhLfibpWpsVBx2n/GKOz6JdGQvLruZQfGr9l1qes2KQaWswjBzhQF7UDUZMNaMMQeYnQzxwOMPsbYF7wqPQ== +"@babel/plugin-transform-classes@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.6.tgz#e04d7d804ed5b8501311293d1a0e6d43e94c3363" + integrity sha512-58EgM6nuPNG6Py4Z3zSuu0xWu2VfodiMi72Jt5Kj2FECmaYk1RrTXA45z6KBFsu9tRgwQDwIiY4FXTt+YsSFAQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.6" "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-function-name" "^7.22.5" "@babel/helper-optimise-call-expression" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-replace-supers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" globals "^11.1.0" "@babel/plugin-transform-computed-properties@^7.22.5": @@ -897,10 +861,10 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-optional-chaining@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.5.tgz#1003762b9c14295501beb41be72426736bedd1e0" - integrity sha512-AconbMKOMkyG+xCng2JogMCDcqW8wedQAqpVIL4cOSescZ7+iW8utC6YDZLMCSUIReEA733gzRSaOSXMAt/4WQ== +"@babel/plugin-transform-optional-chaining@^7.22.5", "@babel/plugin-transform-optional-chaining@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.22.6.tgz#4bacfe37001fe1901117672875e931d439811564" + integrity sha512-Vd5HiWml0mDVtcLHIoEU5sw6HOUW/Zk0acLs/SAeuLzkGNOPc9DB4nkUajemhCmTIz3eiaKREZn2hQQqF79YTg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" @@ -994,16 +958,16 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-runtime@^7.16.4": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.5.tgz#ca975fb5e260044473c8142e1b18b567d33c2a3b" - integrity sha512-bg4Wxd1FWeFx3daHFTWk1pkSWK/AyQuiyAoeZAOkAOUBjnZPH6KT7eMxouV47tQ6hl6ax2zyAWBdWZXbrvXlaw== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.22.9.tgz#a87b11e170cbbfb018e6a2bf91f5c6e533b9e027" + integrity sha512-9KjBH61AGJetCPYp/IEyLEp47SyybZb0nDRpBvmtEkm+rUIwxdlKpyNHI1TmsGkeuLclJdleQHRZ8XLBnnh8CQ== dependencies: "@babel/helper-module-imports" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" - babel-plugin-polyfill-corejs2 "^0.4.3" - babel-plugin-polyfill-corejs3 "^0.8.1" - babel-plugin-polyfill-regenerator "^0.5.0" - semver "^6.3.0" + babel-plugin-polyfill-corejs2 "^0.4.4" + babel-plugin-polyfill-corejs3 "^0.8.2" + babel-plugin-polyfill-regenerator "^0.5.1" + semver "^6.3.1" "@babel/plugin-transform-shorthand-properties@^7.22.5": version "7.22.5" @@ -1042,12 +1006,12 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-typescript@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.5.tgz#5c0f7adfc1b5f38c4dbc8f79b1f0f8074134bd7d" - integrity sha512-SMubA9S7Cb5sGSFFUlqxyClTA9zWJ8qGQrppNUm05LtFuN1ELRFNndkix4zUJrC9F+YivWwa1dHMSyo0e0N9dA== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.9.tgz#91e08ad1eb1028ecc62662a842e93ecfbf3c7234" + integrity sha512-BnVR1CpKiuD0iobHPaM1iLvcwPYN2uVFAqoLVSpEDKWuOikoCv5HbKLxclhKYUXlWkX86DoZGtqI4XhbOsyrMg== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.9" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-typescript" "^7.22.5" @@ -1083,12 +1047,12 @@ "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-env@^7.11.0", "@babel/preset-env@^7.12.1", "@babel/preset-env@^7.16.4": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.5.tgz#3da66078b181f3d62512c51cf7014392c511504e" - integrity sha512-fj06hw89dpiZzGZtxn+QybifF07nNiZjZ7sazs2aVDcysAZVGjW7+7iFYxg6GLNM47R/thYfLdrXc+2f11Vi9A== + version "7.22.9" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.22.9.tgz#57f17108eb5dfd4c5c25a44c1977eba1df310ac7" + integrity sha512-wNi5H/Emkhll/bqPjsjQorSykrlfY5OWakd6AulLvMEytpKasMVUpVy8RL4qBIBs5Ac6/5i0/Rv0b/Fg6Eag/g== dependencies: - "@babel/compat-data" "^7.22.5" - "@babel/helper-compilation-targets" "^7.22.5" + "@babel/compat-data" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.9" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-option" "^7.22.5" "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.5" @@ -1113,13 +1077,13 @@ "@babel/plugin-syntax-top-level-await" "^7.14.5" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" "@babel/plugin-transform-arrow-functions" "^7.22.5" - "@babel/plugin-transform-async-generator-functions" "^7.22.5" + "@babel/plugin-transform-async-generator-functions" "^7.22.7" "@babel/plugin-transform-async-to-generator" "^7.22.5" "@babel/plugin-transform-block-scoped-functions" "^7.22.5" "@babel/plugin-transform-block-scoping" "^7.22.5" "@babel/plugin-transform-class-properties" "^7.22.5" "@babel/plugin-transform-class-static-block" "^7.22.5" - "@babel/plugin-transform-classes" "^7.22.5" + "@babel/plugin-transform-classes" "^7.22.6" "@babel/plugin-transform-computed-properties" "^7.22.5" "@babel/plugin-transform-destructuring" "^7.22.5" "@babel/plugin-transform-dotall-regex" "^7.22.5" @@ -1144,7 +1108,7 @@ "@babel/plugin-transform-object-rest-spread" "^7.22.5" "@babel/plugin-transform-object-super" "^7.22.5" "@babel/plugin-transform-optional-catch-binding" "^7.22.5" - "@babel/plugin-transform-optional-chaining" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.6" "@babel/plugin-transform-parameters" "^7.22.5" "@babel/plugin-transform-private-methods" "^7.22.5" "@babel/plugin-transform-private-property-in-object" "^7.22.5" @@ -1162,11 +1126,11 @@ "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" "@babel/preset-modules" "^0.1.5" "@babel/types" "^7.22.5" - babel-plugin-polyfill-corejs2 "^0.4.3" - babel-plugin-polyfill-corejs3 "^0.8.1" - babel-plugin-polyfill-regenerator "^0.5.0" - core-js-compat "^3.30.2" - semver "^6.3.0" + babel-plugin-polyfill-corejs2 "^0.4.4" + babel-plugin-polyfill-corejs3 "^0.8.2" + babel-plugin-polyfill-regenerator "^0.5.1" + core-js-compat "^3.31.0" + semver "^6.3.1" "@babel/preset-modules@^0.1.5": version "0.1.5" @@ -1208,9 +1172,9 @@ integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.4", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.16.3", "@babel/runtime@^7.20.7", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec" - integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA== + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.6.tgz#57d64b9ae3cff1d67eb067ae117dac087f5bd438" + integrity sha512-wDb5pWm4WDdF6LFUde3Jl8WzPA+3ZbxYqkC6xAXuD3irdEHN1k0NfTRrJD8ZD378SJ61miMLCqIOXYhd8x+AJQ== dependencies: regenerator-runtime "^0.13.11" @@ -1223,18 +1187,18 @@ "@babel/parser" "^7.22.5" "@babel/types" "^7.22.5" -"@babel/traverse@^7.12.5", "@babel/traverse@^7.22.5", "@babel/traverse@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.5.tgz#44bd276690db6f4940fdb84e1cb4abd2f729ccd1" - integrity sha512-7DuIjPgERaNo6r+PZwItpjCZEa5vyw4eJGufeLxrPdBXBoLcCJCIasvK6pK/9DVNrLZTLFhUGqaC6X/PA007TQ== +"@babel/traverse@^7.12.5", "@babel/traverse@^7.22.6", "@babel/traverse@^7.22.8", "@babel/traverse@^7.7.2": + version "7.22.8" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.22.8.tgz#4d4451d31bc34efeae01eac222b514a77aa4000e" + integrity sha512-y6LPR+wpM2I3qJrsheCTwhIinzkETbplIgPBbwvqPKc+uljeA5gP+3nP8irdYt1mjQaDnlIcG+dw8OjAco4GXw== dependencies: "@babel/code-frame" "^7.22.5" - "@babel/generator" "^7.22.5" + "@babel/generator" "^7.22.7" "@babel/helper-environment-visitor" "^7.22.5" "@babel/helper-function-name" "^7.22.5" "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.5" - "@babel/parser" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.22.7" "@babel/types" "^7.22.5" debug "^4.1.0" globals "^11.1.0" @@ -1381,14 +1345,14 @@ resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.5.1.tgz#cdd35dce4fa1a89a4fd42b1599eb35b3af408884" integrity sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ== -"@eslint/eslintrc@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.0.3.tgz#4910db5505f4d503f27774bf356e3704818a0331" - integrity sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ== +"@eslint/eslintrc@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.0.tgz#82256f164cc9e0b59669efc19d57f8092706841d" + integrity sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A== dependencies: ajv "^6.12.4" debug "^4.3.2" - espree "^9.5.2" + espree "^9.6.0" globals "^13.19.0" ignore "^5.2.0" import-fresh "^3.2.1" @@ -1396,10 +1360,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.43.0": - version "8.43.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.43.0.tgz#559ca3d9ddbd6bf907ad524320a0d14b85586af0" - integrity sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg== +"@eslint/js@8.44.0": + version "8.44.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.44.0.tgz#961a5903c74139390478bdc808bcde3fc45ab7af" + integrity sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw== "@floating-ui/core@^1.3.1": version "1.3.1" @@ -1407,9 +1371,9 @@ integrity sha512-Bu+AMaXNjrpjh41znzHqaz3r2Nr8hHuHZT6V2LBKMhyMl0FgKA62PNYbqnfgmzOhoWZj70Zecisbo4H1rotP5g== "@floating-ui/dom@^1.2.0": - version "1.4.2" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.4.2.tgz#eb3a37f7506c4f95ef735967dc3496b5012e11cb" - integrity sha512-VKmvHVatWnewmGGy+7Mdy4cTJX71Pli6v/Wjb5RQBuq5wjUYx+Ef+kRThi8qggZqDgD8CogCpqhRoVp3+yQk+g== + version "1.4.5" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.4.5.tgz#336dfb9870c98b471ff5802002982e489b8bd1c5" + integrity sha512-96KnRWkRnuBSSFbj0sFGwwOUd8EkiecINVl0O9wiZlZ64EkpyAOG3Xc2vKKNJmru0Z7RqWNymA+6b8OZqjgyyw== dependencies: "@floating-ui/core" "^1.3.1" @@ -1436,81 +1400,81 @@ dependencies: "@swc/helpers" "^0.4.14" -"@fluentui/priority-overflow@^9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@fluentui/priority-overflow/-/priority-overflow-9.1.0.tgz#db3ba35f7dea2a254d326e02a77abc1844ab5306" - integrity sha512-4QMDdS0zFV/sce9fI8I+p0xbnO1pABbQ2qYKYb6eSf27v7m5q3TCUkT//f6WKwptk+GzCuViD6jV3CHB1PlrSw== +"@fluentui/priority-overflow@^9.1.1": + version "9.1.1" + resolved "https://registry.yarnpkg.com/@fluentui/priority-overflow/-/priority-overflow-9.1.1.tgz#c9e9e0e45cb152a582c242ac4c73e09d6a6f90b0" + integrity sha512-wYCZbGHrApTaVnlpvWkgIy/NPSyexl7pRO14lSo9LW9dDcojiHI3KWtpRxO3/tf6LtHuUBNe/+vonGJUsSI68w== dependencies: "@swc/helpers" "^0.4.14" -"@fluentui/react-accordion@^9.1.17": - version "9.1.17" - resolved "https://registry.yarnpkg.com/@fluentui/react-accordion/-/react-accordion-9.1.17.tgz#386e6b58e4158e7079ac134595319713ce09e709" - integrity sha512-Deft6PCH9FJkTNcjpTb4emkXU2Hr7QAza3v5dCsXZqHvUn5coTh9vUucCgJuez7DELGdKhY3GlOgVLXp6fHp1A== +"@fluentui/react-accordion@^9.1.23": + version "9.1.23" + resolved "https://registry.yarnpkg.com/@fluentui/react-accordion/-/react-accordion-9.1.23.tgz#a3339ea748851ec67a24d96351686f45999decd7" + integrity sha512-Cast99R8Tq/Z+jyriZxd1hOeNkgfe1WZiOi5DLd3Ow0H1Os2HJDss/YgpU3ZHXHY/A/AcHWNzwv801Ub8mhBhA== dependencies: - "@fluentui/react-aria" "^9.3.23" - "@fluentui/react-context-selector" "^9.1.23" + "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-alert@9.0.0-beta.52": - version "9.0.0-beta.52" - resolved "https://registry.yarnpkg.com/@fluentui/react-alert/-/react-alert-9.0.0-beta.52.tgz#ff15411e8b22796981e1dc5b05204a1f24e0c228" - integrity sha512-sU/0p+xayV+iBk2pEfFZaLcEmdTwIiMf1WzX4KQk7Rzsvy+Bez67+8zRh6OsUPEKIModruDeMmSflw57ridqyQ== +"@fluentui/react-alert@9.0.0-beta.58": + version "9.0.0-beta.58" + resolved "https://registry.yarnpkg.com/@fluentui/react-alert/-/react-alert-9.0.0-beta.58.tgz#0b32c918aa1bc1547f26c60680c01c19109560b8" + integrity sha512-i4JZIW0YAxaNslcI5YAx7KrjWxVYCOqVWI+kZ+pD2bsSYzuh2XNoddi/VVJAK/ckpafM3ZDVW7ZfTmZ9O/XaHg== dependencies: - "@fluentui/react-avatar" "^9.5.6" - "@fluentui/react-button" "^9.3.17" + "@fluentui/react-avatar" "^9.5.12" + "@fluentui/react-button" "^9.3.23" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-aria@^9.3.23": - version "9.3.23" - resolved "https://registry.yarnpkg.com/@fluentui/react-aria/-/react-aria-9.3.23.tgz#316826eb9182dc3e9aaa790a4b2920355f272c60" - integrity sha512-HuZW1cweaJzcvthgU0dBB9tiXAprAowlBEujyW3nDAx1UzjrHIQun2yiX/wsdo9UADdvEbtYFKC7YmYVIUEiKA== +"@fluentui/react-aria@^9.3.26": + version "9.3.26" + resolved "https://registry.yarnpkg.com/@fluentui/react-aria/-/react-aria-9.3.26.tgz#03e0ea8f6fa80b5e07f171f010b4634369d0da5b" + integrity sha512-3COvfltw3yn0p93HBWf1XmOv5A/sJ1jfsxtNeoum0+RivMs+L9CgTS5/d86t8xiQrxw1JXtWBzDaBwHBasE6Aw== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@swc/helpers" "^0.4.14" -"@fluentui/react-avatar@^9.5.6": - version "9.5.6" - resolved "https://registry.yarnpkg.com/@fluentui/react-avatar/-/react-avatar-9.5.6.tgz#e291c72c1a494e240a733746fced1f7524f16998" - integrity sha512-IbnHVjgDCzHjoZmF8KIzCg8FJxsd9N5iJFXW1qwX2d/YSj+Qrmxi3wNA//EwCFrpUAoZeZH6JRWmynQAGaZHoQ== +"@fluentui/react-avatar@^9.5.12": + version "9.5.12" + resolved "https://registry.yarnpkg.com/@fluentui/react-avatar/-/react-avatar-9.5.12.tgz#de63336de6696b605f5cfe6c4c95ff0465f9964e" + integrity sha512-Z5frthUPQQjJjzP5MZEXzzw5WymKvBfESAnW45+ZeJezgY/RBPxV8QgT+l39MeNeULjZgtTU7sH0m6NejQBt8g== dependencies: - "@fluentui/react-badge" "^9.1.16" - "@fluentui/react-context-selector" "^9.1.23" + "@fluentui/react-badge" "^9.1.20" + "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-popover" "^9.7.0" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-popover" "^9.7.6" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-tooltip" "^9.2.17" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-tooltip" "^9.2.23" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-badge@^9.1.16": - version "9.1.16" - resolved "https://registry.yarnpkg.com/@fluentui/react-badge/-/react-badge-9.1.16.tgz#8b960b200f55d72c4b3187f8038a7260469a514d" - integrity sha512-38KTwajnSLX1c5JMz3ywENHZHYVzmRhAEKvdp382zPDiSHL4ejrMj/33AU3UqeObGsNK8l++M++f15qBOoODeA== +"@fluentui/react-badge@^9.1.20": + version "9.1.20" + resolved "https://registry.yarnpkg.com/@fluentui/react-badge/-/react-badge-9.1.20.tgz#c8ec521666de09248f833eb7470116410ace0b47" + integrity sha512-vfbooJgbVIUITsNUprS4C8/HYbhyZS2JhLXzHnrrxF9/VxgLMjVY49neCFyNmLRp4VCi92ECMz6ekFzL2cym+g== dependencies: "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" @@ -1533,66 +1497,66 @@ prop-types "^15.7.2" react-is "^17.0.2" -"@fluentui/react-button@^9.3.17": - version "9.3.17" - resolved "https://registry.yarnpkg.com/@fluentui/react-button/-/react-button-9.3.17.tgz#df0e003cc15c1d254ab97e476160dd80c4167676" - integrity sha512-QQe7juuehcalCBQWGfypRi9VEs8iwbgFFyo8JGdC2UKV/bDjO2CfYU4V6IHgoqQ6vX09mAshLIuZz1kwfgiCxg== +"@fluentui/react-button@^9.3.23": + version "9.3.23" + resolved "https://registry.yarnpkg.com/@fluentui/react-button/-/react-button-9.3.23.tgz#4647a6cb14634fd86803be335efc1df00e217a68" + integrity sha512-YzBmu8gV06j9TyioPHThSeybCkNlVnKJRXY/XKS+8mkJBOZA0ZsKv3UwlSQHyM1Ov4wku2JPCotW37lbUOOKLg== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.23" + "@fluentui/react-aria" "^9.3.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-card@^9.0.15": - version "9.0.15" - resolved "https://registry.yarnpkg.com/@fluentui/react-card/-/react-card-9.0.15.tgz#e19d89f6796dc6fffb705669b684d46051593827" - integrity sha512-zjWbo2ejjCzOoNnt2ncOl9M8vVJMOl8bO7Kcpl+n28QHmN0KJvyMvAOpvrgBXbJL+kkLWPr9TNDRoYhTxMmIBA== +"@fluentui/react-card@^9.0.22": + version "9.0.22" + resolved "https://registry.yarnpkg.com/@fluentui/react-card/-/react-card-9.0.22.tgz#0388853d58d94fcc9db7d9539692cdb7a4227090" + integrity sha512-/ay8kMPKn7/utLAvaIbUuro2FMxkpJ+klzwm7I4AGOOrpLr5ajsYQ5LX6W3FrMsLgGZFKXFpM4sl7qOgsI28Cg== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-checkbox@^9.1.18": - version "9.1.18" - resolved "https://registry.yarnpkg.com/@fluentui/react-checkbox/-/react-checkbox-9.1.18.tgz#8253a1a4a97cebbb2ed2f3c1a93bab81d852772c" - integrity sha512-5poEL0HqSOoaQhHKgKmugfaApJsf78yMd+ZjX04j8CYJHZngxN1AVpodOKFBNfrVuP6qJCJXl+MPNTYttbzQSQ== +"@fluentui/react-checkbox@^9.1.24": + version "9.1.24" + resolved "https://registry.yarnpkg.com/@fluentui/react-checkbox/-/react-checkbox-9.1.24.tgz#0e90386fcc00b37b86376356aec72ebf4117e6fb" + integrity sha512-S4eUBaTMgzL5eDVhSymL6R9dHc3aV61OTojrRjXyc0utUhziCtijj9uZ0jlQ4G5l5ZrQcfpDZQxuSDOGQ2Mcpg== dependencies: - "@fluentui/react-field" "^9.1.7" + "@fluentui/react-field" "^9.1.11" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-label" "^9.1.16" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-label" "^9.1.20" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-combobox@^9.4.1": - version "9.4.1" - resolved "https://registry.yarnpkg.com/@fluentui/react-combobox/-/react-combobox-9.4.1.tgz#02d43c976ce9876d6f3ca24ee530749652d70b67" - integrity sha512-uVk5c6i9Qszbwe0OHMQ8evnIoJkvNF7B18+i03TRslKmH8jdg8qQYBV03ARiwEvRf1/ADxJwanvZweagiqJfLA== +"@fluentui/react-combobox@^9.4.7": + version "9.4.7" + resolved "https://registry.yarnpkg.com/@fluentui/react-combobox/-/react-combobox-9.4.7.tgz#2bfc30ad4964446ec0242a8b89995f3e47d59716" + integrity sha512-dr9DvEtCl7v3/4TeAVQ2a7ynRYuxRTjRd5UFoZSg2p5/iot4F1Xk2Q8/mEj7T4/nZy5gaK5F3k6V54YjYrsdHQ== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-context-selector" "^9.1.23" - "@fluentui/react-field" "^9.1.7" + "@fluentui/react-context-selector" "^9.1.26" + "@fluentui/react-field" "^9.1.11" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-portal" "^9.2.13" - "@fluentui/react-positioning" "^9.7.0" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-positioning" "^9.8.0" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" @@ -1620,119 +1584,120 @@ react-is "^17.0.2" "@fluentui/react-components@^9.13.0": - version "9.22.0" - resolved "https://registry.yarnpkg.com/@fluentui/react-components/-/react-components-9.22.0.tgz#0eb1868d58a3a02d1a1873f6331b06998b388f71" - integrity sha512-3BtJMWnHWiL2iK5/HRA1vEFy3fExBb2mp3qJ01PocWOOHoGx2HiL3Mnmn9iVuOQGU/AT0VB9mdxObkspxi6Bcw== - dependencies: - "@fluentui/react-accordion" "^9.1.17" - "@fluentui/react-alert" "9.0.0-beta.52" - "@fluentui/react-avatar" "^9.5.6" - "@fluentui/react-badge" "^9.1.16" - "@fluentui/react-button" "^9.3.17" - "@fluentui/react-card" "^9.0.15" - "@fluentui/react-checkbox" "^9.1.18" - "@fluentui/react-combobox" "^9.4.1" - "@fluentui/react-dialog" "^9.5.10" - "@fluentui/react-divider" "^9.2.16" - "@fluentui/react-drawer" "9.0.0-beta.2" - "@fluentui/react-field" "^9.1.7" - "@fluentui/react-image" "^9.1.13" - "@fluentui/react-infobutton" "9.0.0-beta.35" - "@fluentui/react-input" "^9.4.17" - "@fluentui/react-label" "^9.1.16" - "@fluentui/react-link" "^9.0.43" - "@fluentui/react-menu" "^9.8.0" - "@fluentui/react-overflow" "^9.0.20" - "@fluentui/react-persona" "^9.2.16" - "@fluentui/react-popover" "^9.7.0" - "@fluentui/react-portal" "^9.2.13" - "@fluentui/react-positioning" "^9.7.0" - "@fluentui/react-progress" "^9.1.17" - "@fluentui/react-provider" "^9.7.3" - "@fluentui/react-radio" "^9.1.18" - "@fluentui/react-select" "^9.1.17" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-skeleton" "^9.0.5" - "@fluentui/react-slider" "^9.1.18" - "@fluentui/react-spinbutton" "^9.2.17" - "@fluentui/react-spinner" "^9.2.3" - "@fluentui/react-switch" "^9.1.18" - "@fluentui/react-table" "^9.4.0" - "@fluentui/react-tabs" "^9.3.18" - "@fluentui/react-tabster" "^9.8.0" - "@fluentui/react-text" "^9.3.13" - "@fluentui/react-textarea" "^9.3.17" + version "9.26.1" + resolved "https://registry.yarnpkg.com/@fluentui/react-components/-/react-components-9.26.1.tgz#ddc907a9062e98ccd357ac8982a986177d7e9aa3" + integrity sha512-IeGamHc0D0IjkYxLBTqnDdZkLrKLh5x+8k++0sihkNxmVmjZUB0ZyYq7F0z6pv8XuyMjcJhvG/StuJcVOorqLQ== + dependencies: + "@fluentui/react-accordion" "^9.1.23" + "@fluentui/react-alert" "9.0.0-beta.58" + "@fluentui/react-avatar" "^9.5.12" + "@fluentui/react-badge" "^9.1.20" + "@fluentui/react-button" "^9.3.23" + "@fluentui/react-card" "^9.0.22" + "@fluentui/react-checkbox" "^9.1.24" + "@fluentui/react-combobox" "^9.4.7" + "@fluentui/react-dialog" "^9.5.16" + "@fluentui/react-divider" "^9.2.20" + "@fluentui/react-drawer" "9.0.0-beta.8" + "@fluentui/react-field" "^9.1.11" + "@fluentui/react-image" "^9.1.17" + "@fluentui/react-infobutton" "9.0.0-beta.42" + "@fluentui/react-input" "^9.4.21" + "@fluentui/react-label" "^9.1.20" + "@fluentui/react-link" "^9.1.2" + "@fluentui/react-menu" "^9.10.0" + "@fluentui/react-overflow" "^9.0.23" + "@fluentui/react-persona" "^9.2.22" + "@fluentui/react-popover" "^9.7.6" + "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-positioning" "^9.8.0" + "@fluentui/react-progress" "^9.1.21" + "@fluentui/react-provider" "^9.7.9" + "@fluentui/react-radio" "^9.1.24" + "@fluentui/react-select" "^9.1.21" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-skeleton" "^9.0.9" + "@fluentui/react-slider" "^9.1.24" + "@fluentui/react-spinbutton" "^9.2.21" + "@fluentui/react-spinner" "^9.3.0" + "@fluentui/react-switch" "^9.1.24" + "@fluentui/react-table" "^9.6.0" + "@fluentui/react-tabs" "^9.3.24" + "@fluentui/react-tabster" "^9.10.0" + "@fluentui/react-text" "^9.3.17" + "@fluentui/react-textarea" "^9.3.21" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-toolbar" "^9.1.18" - "@fluentui/react-tooltip" "^9.2.17" - "@fluentui/react-tree" "9.0.0-beta.19" - "@fluentui/react-utilities" "^9.9.3" - "@fluentui/react-virtualizer" "9.0.0-alpha.23" + "@fluentui/react-toast" "^9.0.3" + "@fluentui/react-toolbar" "^9.1.24" + "@fluentui/react-tooltip" "^9.2.23" + "@fluentui/react-tree" "9.0.0-beta.25" + "@fluentui/react-utilities" "^9.10.1" + "@fluentui/react-virtualizer" "9.0.0-alpha.28" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-context-selector@^9.1.23": - version "9.1.23" - resolved "https://registry.yarnpkg.com/@fluentui/react-context-selector/-/react-context-selector-9.1.23.tgz#f92ab0a7ce508e819826af1b407d0d58cd910e92" - integrity sha512-ZJsRmIwkslcm8lVJiFXrUZlH+dO5/iDvmo42wHuREV7yNe82QnZLL1kMTKmtkll2KH8SCFwOEp4OeYudWUc2ZA== +"@fluentui/react-context-selector@^9.1.26": + version "9.1.26" + resolved "https://registry.yarnpkg.com/@fluentui/react-context-selector/-/react-context-selector-9.1.26.tgz#d172dd81271ca363b0c8e34e3a1bcc657f624492" + integrity sha512-9Pbo2GpnkZH7eoVvhCppnENmAI8Z8Asb6GC9YySMoLbM2NPkqdCcOwyKEnIc/J9LQoyPkFuSL5Msf7Y84coTiw== dependencies: - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@swc/helpers" "^0.4.14" -"@fluentui/react-dialog@^9.5.10": - version "9.5.10" - resolved "https://registry.yarnpkg.com/@fluentui/react-dialog/-/react-dialog-9.5.10.tgz#95c547b82d20b46eae0d55e6dd928458c3b710a0" - integrity sha512-7U3PW5LLeEXd83UFFkqeN5O+/knS0DTK28kR39ORpeX6V+ulpoi4y/fYzsOovKX9QZQG/wWvn2wng+wAjjCYRA== +"@fluentui/react-dialog@^9.5.16": + version "9.5.16" + resolved "https://registry.yarnpkg.com/@fluentui/react-dialog/-/react-dialog-9.5.16.tgz#8c67ceadffbef2802090ea9bf5b33cc726594081" + integrity sha512-3zSKF23Y4/JJ3uqb+R//w5B93CIYsC/jKpqQR8+mHPnmRksCsQwa7BGqABXJoo7+JfGmWWhIDAZCdXmzgyjMCw== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.23" - "@fluentui/react-context-selector" "^9.1.23" + "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-portal" "^9.2.13" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-divider@^9.2.16": - version "9.2.16" - resolved "https://registry.yarnpkg.com/@fluentui/react-divider/-/react-divider-9.2.16.tgz#bfabe8f047abb23b44296b5f3f5bef894e5eb725" - integrity sha512-S+2OrGWZ+gQTrhwTxaa7QzTZB9D06uO74O/gapX/HTfqfHsKjG9w5ELL8rQhROAOqND7gkUfIFPxgiDAEfqdPg== +"@fluentui/react-divider@^9.2.20": + version "9.2.20" + resolved "https://registry.yarnpkg.com/@fluentui/react-divider/-/react-divider-9.2.20.tgz#5a45af171178c5a1178e8286a586fd56f8a339f2" + integrity sha512-Sb2/VFfCjXPOLqaQHFZaWpaoA31XiNS11tPlrO0Pe5TveOI5ifH2UhIuIVv+0C+Asjn5wmUdZfWaMMCduSJHLw== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-drawer@9.0.0-beta.2": - version "9.0.0-beta.2" - resolved "https://registry.yarnpkg.com/@fluentui/react-drawer/-/react-drawer-9.0.0-beta.2.tgz#6745dfde6ed85e666721618b4c3c1ac66e710c2d" - integrity sha512-YbXv7Qo/X34OnS1IouhWzSi4WEwxK82UwZ2hvwtbRJ8HpUZ72vabRBNIBvFRNd1N9Iq8a9NxH0YMfCHeSuwmng== +"@fluentui/react-drawer@9.0.0-beta.8": + version "9.0.0-beta.8" + resolved "https://registry.yarnpkg.com/@fluentui/react-drawer/-/react-drawer-9.0.0-beta.8.tgz#74d14b946fb5f67fc1b389a67f90aceab754a88d" + integrity sha512-YWCgMX/g/2GZzCEyLFmqk9jhbUYIps/u1mYg9bWiRLd3tAjGEK3mMUDLmtRYaEZn2J1g2DIr1XTP+R9S4VT89A== dependencies: - "@fluentui/react-dialog" "^9.5.10" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-dialog" "^9.5.16" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-field@^9.1.7": - version "9.1.7" - resolved "https://registry.yarnpkg.com/@fluentui/react-field/-/react-field-9.1.7.tgz#b04cb8eb10d156a1a8af986de352947332ace7c7" - integrity sha512-siIdeIuIjGhs/Tcgy5kUiJ8iEoi36LbjVcLH81X7BAbvR9skEGdxA3PMj21bS5GCPW/TZe75pd1h6ig+QwOdKg== +"@fluentui/react-field@^9.1.11": + version "9.1.11" + resolved "https://registry.yarnpkg.com/@fluentui/react-field/-/react-field-9.1.11.tgz#109335539180919ebb633b57cce0da8bc5eeb781" + integrity sha512-qPcCWURPBVoRClSSTjoLm7E88kEoyzrHoi62L6qoBdY1d3yKXGKDCBOK1j0FsVg5/WECnUDU8T4DO6KRbpUt3g== dependencies: - "@fluentui/react-context-selector" "^9.1.23" + "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-label" "^9.1.16" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-label" "^9.1.20" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" @@ -1748,102 +1713,103 @@ classnames "^2.2.6" "@fluentui/react-icons@^2.0.193", "@fluentui/react-icons@^2.0.203": - version "2.0.204" - resolved "https://registry.yarnpkg.com/@fluentui/react-icons/-/react-icons-2.0.204.tgz#cc93486e1cbea5f0df2cd6b1648d47fe6eb06557" - integrity sha512-zl1T5CorbJ3cLeM3BfXxT1Bdm1f56gTXagrJG+f+b3gs+bI5qeNmCkZv5yq0DVdWx5KAqYoeX57wkn7GM5GyTA== + version "2.0.207" + resolved "https://registry.yarnpkg.com/@fluentui/react-icons/-/react-icons-2.0.207.tgz#64a4a20e36ec281ef7bd530710219213d485348e" + integrity sha512-MB6vY1yFqGqsO1zFjLQZcPY7dk7TLkFvtVOhjxSuz3KHOI3FKssWjq70H5mOHoWe/1oyWoA0S8tN0W0D+uT3dA== dependencies: "@griffel/react" "^1.0.0" tslib "^2.1.0" -"@fluentui/react-image@^9.1.13": - version "9.1.13" - resolved "https://registry.yarnpkg.com/@fluentui/react-image/-/react-image-9.1.13.tgz#efd1359d96a3669aa6c0d7095dca5183ceb5e0da" - integrity sha512-xT+Eq8m+tJihN5EJ1mdoD72j9NCu8YyY1Aj5QIx2+qeXnv5TF4ZIVp0xk0AoFaDe5F0qSCGRqhfb3L9QMuh/Pg== +"@fluentui/react-image@^9.1.17": + version "9.1.17" + resolved "https://registry.yarnpkg.com/@fluentui/react-image/-/react-image-9.1.17.tgz#9f0418ca49fa004b96fd8997f8698cd7815eb6fc" + integrity sha512-OgFGv+2a/Isc7gDhl/XNAXVsJONYRqlQ4Ar7UPnlJMUuVQWx1pqXWWD8U41YLcLslds8EkiAH5+SWbnDC7XY8Q== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-infobutton@9.0.0-beta.35": - version "9.0.0-beta.35" - resolved "https://registry.yarnpkg.com/@fluentui/react-infobutton/-/react-infobutton-9.0.0-beta.35.tgz#91638e9ca7a9fd9ce5166f1939d6f905216515ec" - integrity sha512-1Dk6P95bOyd73re7hG3hHRAnDcnjPj0Yu/iWYACu+rSk1zQoCsoKON3pVq0LnkZUyXNBNoGbgGdz75r92i93hg== +"@fluentui/react-infobutton@9.0.0-beta.42": + version "9.0.0-beta.42" + resolved "https://registry.yarnpkg.com/@fluentui/react-infobutton/-/react-infobutton-9.0.0-beta.42.tgz#e35e6b476dbe5d7e3cee42ce14f92f5b710f8e70" + integrity sha512-3yQBurgNpy06AvezRNhxuXiT9nUDrF62ZV5G7DaTx1o73e7kmO55DQbUKhsDOwyEe+rgKVFFmmW/SZwN/RZQ+w== dependencies: "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-label" "^9.1.16" - "@fluentui/react-popover" "^9.7.0" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-label" "^9.1.20" + "@fluentui/react-popover" "^9.7.6" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-input@^9.4.17": - version "9.4.17" - resolved "https://registry.yarnpkg.com/@fluentui/react-input/-/react-input-9.4.17.tgz#85864c49ecf912fe17dbd573590c3dbd7e5eaa77" - integrity sha512-lZ0wMws5vd1lyFwExtXNppIrFaTHWFP/fjQ6iM/dTLP0L26dOlxdBmM34VZ+EfES6+GCzqd1Qm+ZhmhzfIP/7w== +"@fluentui/react-input@^9.4.21": + version "9.4.21" + resolved "https://registry.yarnpkg.com/@fluentui/react-input/-/react-input-9.4.21.tgz#0bea45130dd8c3f75a7a02b1472c6b9161ab1b93" + integrity sha512-Ac1y5z7lnU1F4QeaXdKDkF/vxA3Ioq4jjuTCGOESFSyMQ5PuA2plP30hyke1G/VneLyBb07zI/1OWAk1mkc+IQ== dependencies: - "@fluentui/react-field" "^9.1.7" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-field" "^9.1.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-jsx-runtime@9.0.0-alpha.7": - version "9.0.0-alpha.7" - resolved "https://registry.yarnpkg.com/@fluentui/react-jsx-runtime/-/react-jsx-runtime-9.0.0-alpha.7.tgz#cb8835190dddc419494a05d0337789a153b91168" - integrity sha512-UrnsUXrcGKPT08IDDckCiJWXZG8mU3IY8vxHHs4Il6nv6rE+e0GEkz4Ou3Y2QAUBZzyZE+JGeBiwyoGbkASiuA== +"@fluentui/react-jsx-runtime@9.0.0-alpha.11": + version "9.0.0-alpha.11" + resolved "https://registry.yarnpkg.com/@fluentui/react-jsx-runtime/-/react-jsx-runtime-9.0.0-alpha.11.tgz#e84da424f4c8b8d6c8c1df04de62a0392f310188" + integrity sha512-DWX0mSnwXKqIiDE/dE976Qt3ii3covFifMYXQ6v6BdA1cu4foYM5XQioPU12UkDiFiQ2BSavLvZk4aEpXcy/Ew== dependencies: - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@swc/helpers" "^0.4.14" -"@fluentui/react-label@^9.1.16": - version "9.1.16" - resolved "https://registry.yarnpkg.com/@fluentui/react-label/-/react-label-9.1.16.tgz#431a5ed34706e8d1c733e5e9de16585ffd6632b4" - integrity sha512-QOWO90BaST3gmSWJCXuf2TDvMV9EMDipcJvQMfirL6BMT7AL64v583nX4oLqJkTlYzJbQaGyFVI1Kw4DYDrnYA== +"@fluentui/react-label@^9.1.20": + version "9.1.20" + resolved "https://registry.yarnpkg.com/@fluentui/react-label/-/react-label-9.1.20.tgz#824b116610aa7e50d5b52db85351129666c8a003" + integrity sha512-7lfVhy1pgJSDGc980s2KlAAY3DVkUVdP81nT7Xq9zxkVgHgtmg2FA//03j/mR+1F2P2011pGgvSl8YxtB69+wQ== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-link@^9.0.43": - version "9.0.43" - resolved "https://registry.yarnpkg.com/@fluentui/react-link/-/react-link-9.0.43.tgz#96a11d204e3f88385be8dd689c057b4d0d26598b" - integrity sha512-ulYTcUYk6og0XtMtr/LXWMawk7TH0jPfOR8ARF7A6EJdgccWo11BqBLyYgrY0juUYZdlh8bxW5M0LnRKz/FKyw== +"@fluentui/react-link@^9.1.2": + version "9.1.2" + resolved "https://registry.yarnpkg.com/@fluentui/react-link/-/react-link-9.1.2.tgz#04e2d48ac0d040b4569c35718ea129047cb0f667" + integrity sha512-QJ/3TtLWvIP06asbhAqE2XE9Y3oH62zyWHtp0XHXR+ljgJNChatVeG9GDhO6CoiJX3lsnR1rwUITY6wAMl2WhA== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-menu@^9.8.0": - version "9.8.0" - resolved "https://registry.yarnpkg.com/@fluentui/react-menu/-/react-menu-9.8.0.tgz#fc5ba10a38e34d09397260d616c67b08e9cd2b2d" - integrity sha512-N01TAOQl0Rwyxb1qhae+4kJUgyVMEH0dlRf00THGiavcaz8869STwhSamSwmBXYABM7InEIQQGPZLrtjIGWFVQ== +"@fluentui/react-menu@^9.10.0": + version "9.10.0" + resolved "https://registry.yarnpkg.com/@fluentui/react-menu/-/react-menu-9.10.0.tgz#5bb49956e7ed3b04d5232d4ee8dcd08e4a83de44" + integrity sha512-Ri5O8rz36EihLD6bEdnwskWnU8WApAcC2DBVXlztEreTJFfP+fIlofNAhaFsPqn9sDM/idDk3BOnR4VfHyN2sQ== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.23" - "@fluentui/react-context-selector" "^9.1.23" + "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-portal" "^9.2.13" - "@fluentui/react-positioning" "^9.7.0" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-positioning" "^9.8.0" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" @@ -1904,47 +1870,47 @@ react-is "^17.0.2" react-transition-group "^4.4.1" -"@fluentui/react-overflow@^9.0.20": - version "9.0.20" - resolved "https://registry.yarnpkg.com/@fluentui/react-overflow/-/react-overflow-9.0.20.tgz#3ee99d43422a931a0f603178d3db40f76a1d30ee" - integrity sha512-MDNPAXaPp2/kMNGWYx0Va8HCSJIvyETgEHXnEIXfk0e3a8HsvsIjuZPtUhbFZde4T4+S3kMc5dZyd1HyRMxzYA== +"@fluentui/react-overflow@^9.0.23": + version "9.0.23" + resolved "https://registry.yarnpkg.com/@fluentui/react-overflow/-/react-overflow-9.0.23.tgz#928c8e672156a3a085c71a560020c6906353291c" + integrity sha512-8NLit3YvFsuDIe6UMxoMXN/VEEnwZe93G/YyL6qq1apCNERKPeaqv7V7xFlHFBnKj29OT/HXM7yfz7BKB18sRw== dependencies: - "@fluentui/priority-overflow" "^9.1.0" - "@fluentui/react-context-selector" "^9.1.23" + "@fluentui/priority-overflow" "^9.1.1" + "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-persona@^9.2.16": - version "9.2.16" - resolved "https://registry.yarnpkg.com/@fluentui/react-persona/-/react-persona-9.2.16.tgz#d776afad7141b4b6963edf9a4036c310d25bafec" - integrity sha512-upOs4Eu9QD/DEj03fEgp2l7h+2heXuQg9/L0n4yWz3DiI53yc7MMuqoXe0KJpLMnIGlQin911HTHA4sj7uw/Ww== +"@fluentui/react-persona@^9.2.22": + version "9.2.22" + resolved "https://registry.yarnpkg.com/@fluentui/react-persona/-/react-persona-9.2.22.tgz#c599bdb85f614235abd8d8b824699200e681f997" + integrity sha512-jBD68JqTLBNmmhKLPH9LrJ1FvosYZnkOpK3kGeS1oO1yr76deCoK0VnnxjICMXfSmDQUTD5swvbbkYW8/eyOqw== dependencies: - "@fluentui/react-avatar" "^9.5.6" - "@fluentui/react-badge" "^9.1.16" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-avatar" "^9.5.12" + "@fluentui/react-badge" "^9.1.20" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-popover@^9.7.0": - version "9.7.0" - resolved "https://registry.yarnpkg.com/@fluentui/react-popover/-/react-popover-9.7.0.tgz#7314d886d2cd7eeee357b0f3af2b13144493b5e7" - integrity sha512-pQ2gfJ+eNW3VX0FRRHuvYKRrOyeoi56D5IZtYpfedAKkHemE0/mZce6uQFok01Snt53QJT/x5Ro82IlXpn6AkA== +"@fluentui/react-popover@^9.7.6": + version "9.7.6" + resolved "https://registry.yarnpkg.com/@fluentui/react-popover/-/react-popover-9.7.6.tgz#77d39c4aea6a3eb40c7a8e65f10090bbabea7475" + integrity sha512-QC+LhWoZ3GFysmcW7ORISYUrGtLJUKPdTHUJE+oM+M8gUSphqfrt4TDBx6H8cjc+KwVa824gpQYlrPjlbM9CKw== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.23" - "@fluentui/react-context-selector" "^9.1.23" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-portal" "^9.2.13" - "@fluentui/react-positioning" "^9.7.0" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-context-selector" "^9.1.26" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-positioning" "^9.8.0" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" @@ -1955,40 +1921,40 @@ dependencies: "@swc/helpers" "^0.4.14" -"@fluentui/react-portal@^9.2.13": - version "9.2.13" - resolved "https://registry.yarnpkg.com/@fluentui/react-portal/-/react-portal-9.2.13.tgz#bbfdf3d43060b9314bca53dacb15968dfbee8c0a" - integrity sha512-2yX+ByPDix42Q6G2jkS/+OTGJyZxxkxkCtw/eI/tERui1fUZbsZPEmxpBl+lqMCveAZpcMe0evXP1CZgPi62MQ== +"@fluentui/react-portal@^9.3.1": + version "9.3.1" + resolved "https://registry.yarnpkg.com/@fluentui/react-portal/-/react-portal-9.3.1.tgz#66bc43a4389c9ba9f1e7e5f824d73cefbc762126" + integrity sha512-jtnX717hr4eFvbPOBmIj8yADN/IKxE+Lk+qlZjoYEy3bdkkmsRAjyhtpAgSU0cpXKKkiGf5eethsFKYbUZxTyA== dependencies: - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" use-disposable "^1.0.1" -"@fluentui/react-positioning@^9.7.0": - version "9.7.0" - resolved "https://registry.yarnpkg.com/@fluentui/react-positioning/-/react-positioning-9.7.0.tgz#c4e890ec6080e660672bd0a86acbc337e4da71a9" - integrity sha512-cGe3E5hcf9Rf3JYsvfV4iJHxEXSLz+oXk7yUiDnjSq67sk1/dzaIdacxjCqp3xuLVXqvkD9+6wKBLIqWJFc5xQ== +"@fluentui/react-positioning@^9.8.0": + version "9.8.0" + resolved "https://registry.yarnpkg.com/@fluentui/react-positioning/-/react-positioning-9.8.0.tgz#45771640b7f9e98ff7b694791381c5d2e0081c4b" + integrity sha512-2eXai4GdLfbKj4AmCPBS1T9PaaqHkfboFMkCI+zOujGSg7FgIz4U3XzSowms9b9g5bKpUDrEExzd396ZMG8Vjw== dependencies: "@floating-ui/dom" "^1.2.0" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-progress@^9.1.17": - version "9.1.17" - resolved "https://registry.yarnpkg.com/@fluentui/react-progress/-/react-progress-9.1.17.tgz#1140a191e5fe9021670da9f64f2f48d620867af6" - integrity sha512-+x1j/kNXzP5kjqlxCdhQxmDTW0Gfg63BJNZ1orcflbIEhJZKauUX/NYWK/xZldgy3Az3vKpkZtNnXfod7eSTqA== +"@fluentui/react-progress@^9.1.21": + version "9.1.21" + resolved "https://registry.yarnpkg.com/@fluentui/react-progress/-/react-progress-9.1.21.tgz#e654ba75d0dbe7db916ee4da25be8e5000e8d2c0" + integrity sha512-BAt9JdsEiMM+HcFZUoiwjtiqPiTci88zc47U1bvySgn+fUBhvBEZwdj7FIZwT01+V+ScLKIWkemUNZveSjXrrA== dependencies: - "@fluentui/react-field" "^9.1.7" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-field" "^9.1.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" @@ -2001,198 +1967,198 @@ lodash "^4.17.15" prop-types "^15.7.2" -"@fluentui/react-provider@^9.7.3": - version "9.7.3" - resolved "https://registry.yarnpkg.com/@fluentui/react-provider/-/react-provider-9.7.3.tgz#f3a279a9f6497a6387d180e88a2331cc7954be56" - integrity sha512-BsDI6c92ZIgvIGWHBSeJVDtisI2ee67au8d0ct+GqsbOxsQ/y/VnoeOkYZFzwahdvFzammeCrWfWiCSxZIwKWQ== +"@fluentui/react-provider@^9.7.9": + version "9.7.9" + resolved "https://registry.yarnpkg.com/@fluentui/react-provider/-/react-provider-9.7.9.tgz#bf11333c19e9388d90a23f0f538f08ac0ce7430c" + integrity sha512-HDRs98kzNQpuW6/XfmtHNSDqSzFqhynIK/3wYbLfd0MOPrg0k2cQ0lVqL7FZyW+xBCHaweiQxT5iWx/SSkazag== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/core" "^1.11.0" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-radio@^9.1.18": - version "9.1.18" - resolved "https://registry.yarnpkg.com/@fluentui/react-radio/-/react-radio-9.1.18.tgz#2e7b264a1325a8454bb31fca7643c72258b06c19" - integrity sha512-DR+1GDHCppYmTThbjoi19IVN7qNwe8WndoW4EVQkp6pcYbeNvvaaw6OedSvAih9EmBkbhWEKInkpsIBMb7U3QA== +"@fluentui/react-radio@^9.1.24": + version "9.1.24" + resolved "https://registry.yarnpkg.com/@fluentui/react-radio/-/react-radio-9.1.24.tgz#35e241ee472ca9368b948986ea44e31634244200" + integrity sha512-b5k405bo2TfFgr5vPiRjMrEIBu2Hcnmif/lmKxkuf9UlKxu+7YzPCEg5ThqIUauj1J4ssVRrM3GoFE6WSqmCVQ== dependencies: - "@fluentui/react-field" "^9.1.7" + "@fluentui/react-field" "^9.1.11" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-label" "^9.1.16" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-label" "^9.1.20" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-select@^9.1.17": - version "9.1.17" - resolved "https://registry.yarnpkg.com/@fluentui/react-select/-/react-select-9.1.17.tgz#2d3a660eb38ba3124635f9c42f51569bd71ecebf" - integrity sha512-E4U6ZPy7pAM9jP2rVc25HCwtxOQjeQr5WOblFk8Fl7NnQTFQrVGFQRj6GAR4jPbRJ245qNnR8GMo3HKMLL/9vA== +"@fluentui/react-select@^9.1.21": + version "9.1.21" + resolved "https://registry.yarnpkg.com/@fluentui/react-select/-/react-select-9.1.21.tgz#420ee0752ae1a54c86e3fdc4b14787d3dede311b" + integrity sha512-5K2KlGzEhfAO0iCwpPPCZn36ATEATt+h0NJ29ZklhRMlSql79WkJ/CKgsEJr4vGOeLRdj2iPdaYdSG7pgGz+jA== dependencies: - "@fluentui/react-field" "^9.1.7" + "@fluentui/react-field" "^9.1.11" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-shared-contexts@^9.5.1": - version "9.5.1" - resolved "https://registry.yarnpkg.com/@fluentui/react-shared-contexts/-/react-shared-contexts-9.5.1.tgz#149c530e64b4c631061d903a1207722e2f7d1cdb" - integrity sha512-n5gsYr372h39Y2+mqqQGi2u4bgmJgQL4aoQOf+wilC5g+g22s+3RHR3y0/dFi3plMiloioQh7ULN6FJgLvfYpQ== +"@fluentui/react-shared-contexts@^9.6.0": + version "9.6.0" + resolved "https://registry.yarnpkg.com/@fluentui/react-shared-contexts/-/react-shared-contexts-9.6.0.tgz#c4d770e31ac6879e82e98be1731e4bec6651913d" + integrity sha512-sFyMPHJB4UgqPAEmxVikDo9mfBYgpm6mHOpMdM3+T7E3BZUY+7rFlo8XVbk6DzuclAIp85YA/ytHkI+jQyn1cw== dependencies: "@fluentui/react-theme" "^9.1.9" "@swc/helpers" "^0.4.14" -"@fluentui/react-skeleton@^9.0.5": - version "9.0.5" - resolved "https://registry.yarnpkg.com/@fluentui/react-skeleton/-/react-skeleton-9.0.5.tgz#478c75434a2a05fdcbc1375fb6ba2716c444e5aa" - integrity sha512-BgA3rXm1jY7s/ejU6z4pBhYUh8lv7DPjqrr9ahCgZiuy0X8AWZlgv6skRFzCWY2cUbHjqLMu53cVCSDS3CgwPg== +"@fluentui/react-skeleton@^9.0.9": + version "9.0.9" + resolved "https://registry.yarnpkg.com/@fluentui/react-skeleton/-/react-skeleton-9.0.9.tgz#3de3934af544de5206208e7c50f5fd4a560dbd6d" + integrity sha512-f361g2t8uthwNuITJLOtRvCbjoveqYTiYhzd0oKwPZlHkz9xZizVnOLYSXFYyMXAOt4F8Ib4sbdSFjNHycAG2A== dependencies: - "@fluentui/react-field" "^9.1.7" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-field" "^9.1.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-slider@^9.1.18": - version "9.1.18" - resolved "https://registry.yarnpkg.com/@fluentui/react-slider/-/react-slider-9.1.18.tgz#8169c27c1c3994e7dbf6f5154253ddbdb3a2ccdd" - integrity sha512-lByxeN3rZu6lRtSEn15DXVVbnA2cdGG65tyKYzFINGs/31ouoo7QuJ468BkQwFUpwSK9pSPaAQRH237WARCSHQ== +"@fluentui/react-slider@^9.1.24": + version "9.1.24" + resolved "https://registry.yarnpkg.com/@fluentui/react-slider/-/react-slider-9.1.24.tgz#6f745ceb38dfbff0354b353db7f1c553e1bface4" + integrity sha512-2aukES7cnh/8UvHR3QhE1zM69emkap0GwuZiwgzia6Rj2oD4N24ZNFFNtCtpDc/L8KKNy9Tut5I/klP0tohD3w== dependencies: - "@fluentui/react-field" "^9.1.7" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-field" "^9.1.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-spinbutton@^9.2.17": - version "9.2.17" - resolved "https://registry.yarnpkg.com/@fluentui/react-spinbutton/-/react-spinbutton-9.2.17.tgz#480c91079ff4f714385535bb733ac4f0cf998605" - integrity sha512-O+gTImayBuXo6B2wmWza3h0XS9iXlkGwCRth3ytdyS4UyM/RhCWzlPW+l5MlHjEENKTTcM7psxo38R0iDy0WaA== +"@fluentui/react-spinbutton@^9.2.21": + version "9.2.21" + resolved "https://registry.yarnpkg.com/@fluentui/react-spinbutton/-/react-spinbutton-9.2.21.tgz#21a7b04fa04609d58f362763a897568af2ed7da9" + integrity sha512-A+qy6fb52Kr16slC+UduZAFhee8Y2HVopepIvujgHoxWx4qvdjIjrlYsQMiat9g+/Fj6e17f2oS3gLF9h9/cpA== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-field" "^9.1.7" + "@fluentui/react-field" "^9.1.11" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-spinner@^9.2.3": - version "9.2.3" - resolved "https://registry.yarnpkg.com/@fluentui/react-spinner/-/react-spinner-9.2.3.tgz#84df1c0905c3a67c17bd150441cecf4e4e27ed8b" - integrity sha512-cmPsRrp/REWQ95i1kosCQa9WDEv1f7QW6peIVO+8c3yxLzuDedV+hbfWmnklK8c2W+G6efh4KBBqMUfkhtt0fg== +"@fluentui/react-spinner@^9.3.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@fluentui/react-spinner/-/react-spinner-9.3.0.tgz#e1f2eb2b0f764370edc2d179926cd2bdb1fd3324" + integrity sha512-7kakV+ujPo249zqhg2AJG0yFZjyiSVHmPq3QjeHtxC7SETTsYrrK1fPTzj3zl9lO+194X1rmYLPcxo1PKEN26g== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-label" "^9.1.16" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-label" "^9.1.20" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-switch@^9.1.18": - version "9.1.18" - resolved "https://registry.yarnpkg.com/@fluentui/react-switch/-/react-switch-9.1.18.tgz#c078d83758568718b0e67b8392cd3169c8e57367" - integrity sha512-TBLhjMbvBVXpdN2mOnzmFTI1EXrkcJPgEuRBZHSM8/roIVacpGTXdyKzqJpwP/jb7C7YyBEAnPS8uUH0UALl3A== +"@fluentui/react-switch@^9.1.24": + version "9.1.24" + resolved "https://registry.yarnpkg.com/@fluentui/react-switch/-/react-switch-9.1.24.tgz#2302373282dc9af4fa5dae3f36e575028e42e8ed" + integrity sha512-FSeQDOGzDERmStDjGr7NO/wQsd4VG7mI6nWYJcK5qIg7TZFFsa8snf8uknL8irf7c5sSfaUDj8DUVcxRq9nH4w== dependencies: - "@fluentui/react-field" "^9.1.7" + "@fluentui/react-field" "^9.1.11" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-label" "^9.1.16" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-label" "^9.1.20" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-table@^9.4.0": - version "9.4.0" - resolved "https://registry.yarnpkg.com/@fluentui/react-table/-/react-table-9.4.0.tgz#55df837d4b0ef76c17121a5058b3ce88b5e7dcfa" - integrity sha512-Opk6GjUWnTMJVKlPz3tAUhTBo3+i+/Rh4PiYXT3N+8MJGg8rKRXnDVwBFe7MtNr0Gg4VcJMVTzOjjfmGofoNyQ== +"@fluentui/react-table@^9.6.0": + version "9.6.0" + resolved "https://registry.yarnpkg.com/@fluentui/react-table/-/react-table-9.6.0.tgz#9ebb0a23fc4268c77dccc80f1eef4971b6d16a21" + integrity sha512-HVJoHvM8k7SkOjuP7aBLpDeoQhtzn2Skh4O9bCDMNaxoHmcgPw9zskt2Kau/wXSx2JyrGGEz707yRb6EgpKlJg== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.23" - "@fluentui/react-avatar" "^9.5.6" - "@fluentui/react-checkbox" "^9.1.18" - "@fluentui/react-context-selector" "^9.1.23" + "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-avatar" "^9.5.12" + "@fluentui/react-checkbox" "^9.1.24" + "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-radio" "^9.1.18" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-radio" "^9.1.24" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-tabs@^9.3.18": - version "9.3.18" - resolved "https://registry.yarnpkg.com/@fluentui/react-tabs/-/react-tabs-9.3.18.tgz#d4a77eaf55ae0e6c9f733c6af3c51f4ae270ff90" - integrity sha512-9bMseqHoFY+GNor40OrITmJqlEvvDZin6UpzXgnPr0dOvuGRs5kdQZFrixbDGpJvomPXOzh9oKkvxWz5S8gU4w== +"@fluentui/react-tabs@^9.3.24": + version "9.3.24" + resolved "https://registry.yarnpkg.com/@fluentui/react-tabs/-/react-tabs-9.3.24.tgz#c39bce6d8cd462c304e41feb644ae9b2fe00004a" + integrity sha512-5gbGcdJV8zvn6XNesniMrlcgLJhcfcpcGXNA/98vb90Kkhe6MSNp9p7dpVVgnhquJ5MZMVLO9OI8Jj1ugU04jQ== dependencies: - "@fluentui/react-context-selector" "^9.1.23" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-context-selector" "^9.1.26" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-tabster@^9.8.0": - version "9.8.0" - resolved "https://registry.yarnpkg.com/@fluentui/react-tabster/-/react-tabster-9.8.0.tgz#1331ca2d346c0fd6d7d23d94a37e2d689e851a8c" - integrity sha512-lZy7U7cQMMnTQNFVjemUWAtGA5PH+gUoBdT9isB6mA7yrypXxib+kLabcEkrSzO7sl5BMvAOwQa9tK/Kdzh+tg== +"@fluentui/react-tabster@^9.10.0": + version "9.10.0" + resolved "https://registry.yarnpkg.com/@fluentui/react-tabster/-/react-tabster-9.10.0.tgz#9c3312a622320d844976c8ac12ef8ce77f92c79d" + integrity sha512-HKA4DLoocDeomdn1l9z1MUeGGkJzzpzgs5y1lSHnF7aWDcagVZGLjkaCknYDjp8NJwyuR9dS6xPpJbEk3N0hIg== dependencies: - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" keyborg "^2.0.0" tabster "^4.5.1" -"@fluentui/react-text@^9.3.13": - version "9.3.13" - resolved "https://registry.yarnpkg.com/@fluentui/react-text/-/react-text-9.3.13.tgz#eed4eb2a6491c9f5066226d0bc397ee9488ca003" - integrity sha512-Pq0WNKTHMwP9K+dXcee1AqCIL3xUn3aU6hA8lwz6Nvn7Sa5OfpKjMtvUsd/lWcJEJB8USArCARO1OwprJTZzuQ== +"@fluentui/react-text@^9.3.17": + version "9.3.17" + resolved "https://registry.yarnpkg.com/@fluentui/react-text/-/react-text-9.3.17.tgz#aaeb56ad6be2c6c727e7f08dbc7dc35a1da69b1e" + integrity sha512-d/fORzmZ3H2n+Ki5nBkA7fvUa+ReOsk3GVxRB0brAmHaO/7nesi7DjnCTw4owv2vkVwXQJfhT7STxAc6TYjkQw== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-textarea@^9.3.17": - version "9.3.17" - resolved "https://registry.yarnpkg.com/@fluentui/react-textarea/-/react-textarea-9.3.17.tgz#7979e108c0d93918b434e342d79b6ae70365e9f8" - integrity sha512-zEKl2wTg54aWZ319ZrY510RntoS2ETXIwIT2d4ltqOezBc49lYL0d7Z06hFOfqvF04KMtQkBpkc6qR+LaVPHwA== +"@fluentui/react-textarea@^9.3.21": + version "9.3.21" + resolved "https://registry.yarnpkg.com/@fluentui/react-textarea/-/react-textarea-9.3.21.tgz#d1c097ca06c2fb03355e0d60d6184d824afed7cc" + integrity sha512-17w3ZdWiysWDp3TLoq72lvNvR3BDmMcjGje3+G0ns+pReqK/CdHl0gTIgiQsPNyWFtck/zDdQ/gfxNND/LXoLw== dependencies: - "@fluentui/react-field" "^9.1.7" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-field" "^9.1.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" @@ -2204,73 +2170,90 @@ "@fluentui/tokens" "1.0.0-alpha.6" "@swc/helpers" "^0.4.14" -"@fluentui/react-toolbar@^9.1.18": - version "9.1.18" - resolved "https://registry.yarnpkg.com/@fluentui/react-toolbar/-/react-toolbar-9.1.18.tgz#576c99f3d497f49f4e5a12e57301d50eec388133" - integrity sha512-u1MefH5AFvEEms5+7DNdZeZg6rCS2zcDB0qXvYXDlu6rulFsXLRlVjsDmbjMcz9CLiX/fg/uYh1rQKAUBLQM7A== - dependencies: - "@fluentui/react-button" "^9.3.17" - "@fluentui/react-context-selector" "^9.1.23" - "@fluentui/react-divider" "^9.2.16" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-radio" "^9.1.18" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" +"@fluentui/react-toast@^9.0.3": + version "9.0.3" + resolved "https://registry.yarnpkg.com/@fluentui/react-toast/-/react-toast-9.0.3.tgz#d0c42612c98cfb4e5a51386f3dd1dcce4aad1989" + integrity sha512-lOwaTwL0xDQhzqCmtvDlm3AcUoHvL8ihlHMbvtylzBlIUigwmwEJF1fUtYIYXiRZoTnjOwPWWhQpbyA4OoVmUw== + dependencies: + "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-icons" "^2.0.203" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" + "@fluentui/react-theme" "^9.1.9" + "@fluentui/react-utilities" "^9.10.1" + "@griffel/react" "^1.5.7" + "@swc/helpers" "^0.4.14" + react-transition-group "^4.4.1" + +"@fluentui/react-toolbar@^9.1.24": + version "9.1.24" + resolved "https://registry.yarnpkg.com/@fluentui/react-toolbar/-/react-toolbar-9.1.24.tgz#d81b7e3cb6be4cee23bccd6aa2320d6fdfb4a035" + integrity sha512-RDRQBDv0LoNUU3Zq8dwQ/SzwjFockf7Ndgxttz8YIxi1vkEOGRvorichV10vhaedbA5PEo6c9m2mxkUR2QO3YQ== + dependencies: + "@fluentui/react-button" "^9.3.23" + "@fluentui/react-context-selector" "^9.1.26" + "@fluentui/react-divider" "^9.2.20" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-radio" "^9.1.24" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-tooltip@^9.2.17": - version "9.2.17" - resolved "https://registry.yarnpkg.com/@fluentui/react-tooltip/-/react-tooltip-9.2.17.tgz#b9e240f4cf05e29c5032972d4707b2a22c7fa0d2" - integrity sha512-giGW6Q1q82zlzEWkEO6mpcMepWg9L88tV126EdhMlqUDBzmTgo5AKC+Xpm06vy74UE3pLXlNuxlQmp+83opIMw== +"@fluentui/react-tooltip@^9.2.23": + version "9.2.23" + resolved "https://registry.yarnpkg.com/@fluentui/react-tooltip/-/react-tooltip-9.2.23.tgz#03212459ccb2945d735aacbb990a33358a83ccec" + integrity sha512-CKwJwi7kgrRYTdaL5G+A56/GHfCVJzCHHtamHzoxEhKeFDoGDy/pGH0rcneR3Jzgthf35TLyJTYO+EWVZvdTWQ== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-portal" "^9.2.13" - "@fluentui/react-positioning" "^9.7.0" - "@fluentui/react-shared-contexts" "^9.5.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-positioning" "^9.8.0" + "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-tree@9.0.0-beta.19": - version "9.0.0-beta.19" - resolved "https://registry.yarnpkg.com/@fluentui/react-tree/-/react-tree-9.0.0-beta.19.tgz#461df63a3d7d061324a87e17957e78e2f2c3b020" - integrity sha512-hzcwuCNbjNU8cXw0cscRTrGqCayuKrnLzS87vndNRtQgTx4ewiF/f84bllICff9kO0uoHLLEcHUICXs20vLZaA== +"@fluentui/react-tree@9.0.0-beta.25": + version "9.0.0-beta.25" + resolved "https://registry.yarnpkg.com/@fluentui/react-tree/-/react-tree-9.0.0-beta.25.tgz#e06f125829837b39cbf69a2438800e2e4574f702" + integrity sha512-T2l0WE4rBBl/CyhTxtxTw/7LuxtmmMBfQ8upaRiHfgigXme2ss1pcQF7mkGhRl2WSxOLeWEHVX1XTdgWhuZp/A== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.23" - "@fluentui/react-avatar" "^9.5.6" - "@fluentui/react-button" "^9.3.17" - "@fluentui/react-context-selector" "^9.1.23" + "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-avatar" "^9.5.12" + "@fluentui/react-button" "^9.3.23" + "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-portal" "^9.2.13" - "@fluentui/react-shared-contexts" "^9.5.1" - "@fluentui/react-tabster" "^9.8.0" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-shared-contexts" "^9.6.0" + "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-utilities@^9.9.3": - version "9.9.3" - resolved "https://registry.yarnpkg.com/@fluentui/react-utilities/-/react-utilities-9.9.3.tgz#df83b5d90cffb4918f26e2d1e298fd432a3bc7b4" - integrity sha512-A4r6lxyYea1n5zKNcrILpyk9wBoAkrq8ZTZCNegULG3EEx9h9NGh1MsQYNcwB1LuumJU6rGaoDS9ZmVhrI55Dw== +"@fluentui/react-utilities@^9.10.1": + version "9.10.1" + resolved "https://registry.yarnpkg.com/@fluentui/react-utilities/-/react-utilities-9.10.1.tgz#efcb019b9a70d7c21623b8599ed0851032d22289" + integrity sha512-TckWldeYrTy4tneWyPV8oHZFbxUZJA3r+cOSN3pNsyxwLs9vYrsZvpvZJTcOF3VNoEJKFDaehnzuBHEUoL7hmQ== dependencies: "@fluentui/keyboard-keys" "^9.0.3" "@swc/helpers" "^0.4.14" -"@fluentui/react-virtualizer@9.0.0-alpha.23": - version "9.0.0-alpha.23" - resolved "https://registry.yarnpkg.com/@fluentui/react-virtualizer/-/react-virtualizer-9.0.0-alpha.23.tgz#9a1c64db6e7a8866975a5bfa2b86c54e1a51bb27" - integrity sha512-4wSvkUEanokKrk9i4Wiq0E2O93OZ4CbV8U4l3Ij5ZZ3aMEj8hrxxDAV/0ncuLuPcsF1Yzw/BuBXHrPPD7q44Gg== +"@fluentui/react-virtualizer@9.0.0-alpha.28": + version "9.0.0-alpha.28" + resolved "https://registry.yarnpkg.com/@fluentui/react-virtualizer/-/react-virtualizer-9.0.0-alpha.28.tgz#b0f2960fd45ebd73f28fdb4a7afcd4466676cd33" + integrity sha512-jqysw3feXlQT0aS+TFTtmS4wtDkCmGbvywXyiPaKFYF1RvA34UXJbxrgB7RXAey6xMPBxwM6tj3Om6/gPiGg+Q== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.7" - "@fluentui/react-utilities" "^9.9.3" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" @@ -2297,25 +2280,33 @@ dependencies: "@swc/helpers" "^0.4.14" -"@griffel/core@^1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@griffel/core/-/core-1.11.0.tgz#42e6e2128624d6c53817a4cfd326003a5c437eab" - integrity sha512-3jlrsJVbNC0avRMfNGWmbklptmtH5s63Gt/xa0zY6+Oa3kU/StNAu+d0LqLChb5egwXrisQIeC+tzzJ+YozGjg== +"@griffel/core@^1.11.0", "@griffel/core@^1.13.1": + version "1.13.1" + resolved "https://registry.yarnpkg.com/@griffel/core/-/core-1.13.1.tgz#6115a8549cc5df3226459313b6793409ed410041" + integrity sha512-+4lY2qXWdLBX9QUmA7B4eY2/7slh7mJtrvgdHfQmcdZ+4RzHh5E2e0ALwuXu7/6ffa7lwAif4u+ke6L14MrQXg== dependencies: "@emotion/hash" "^0.9.0" + "@griffel/style-types" "^1.0.0" csstype "^3.1.2" rtl-css-js "^1.16.1" - stylis "^4.0.13" + stylis "^4.2.0" tslib "^2.1.0" "@griffel/react@^1.0.0", "@griffel/react@^1.5.7": - version "1.5.7" - resolved "https://registry.yarnpkg.com/@griffel/react/-/react-1.5.7.tgz#3a6af337bfe7551798aa2f6dd1df032b5869f278" - integrity sha512-b9/LkkuO512O268jqRpJPso9ROng/kqh81YSTJUL13tT4qPZQnvrdiwoP7ZeqXbG0zzZHLZ3tWUZrCDOl549OQ== + version "1.5.12" + resolved "https://registry.yarnpkg.com/@griffel/react/-/react-1.5.12.tgz#82cf346325b4bb48ad66598015dafc52d3b84abb" + integrity sha512-HofsQm7ZdwhPqiA0RJJZtHfaokiQgmO0m+CtZMGg+Ycz9Up7c/BtfkrL81enIbz5D5Oqg4+kNPm8K61DTadghQ== dependencies: - "@griffel/core" "^1.11.0" + "@griffel/core" "^1.13.1" tslib "^2.1.0" +"@griffel/style-types@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@griffel/style-types/-/style-types-1.0.0.tgz#804e7505b27bc30dd31afed06ad086ccc92c28f9" + integrity sha512-/4I5OYwyCxJ60YJUcwlPQO2vAm2L+JfC5w/6kpdb052NxczI7KqPcgCwnhqhYagCLlJBM8Ur8dBv7lNNLKndNw== + dependencies: + csstype "^3.1.2" + "@humanwhocodes/config-array@^0.11.10": version "0.11.10" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.10.tgz#5a3ffe32cc9306365fb3fd572596cd602d5e12d2" @@ -2581,9 +2572,9 @@ integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== "@jridgewell/source-map@^0.3.3": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.3.tgz#8108265659d4c33e72ffe14e33d6cc5eb59f2fda" - integrity sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg== + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== dependencies: "@jridgewell/gen-mapping" "^0.3.0" "@jridgewell/trace-mapping" "^0.3.9" @@ -2593,7 +2584,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13": +"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.15": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== @@ -2612,9 +2603,9 @@ integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== "@microsoft/signalr@^7.0.5": - version "7.0.7" - resolved "https://registry.yarnpkg.com/@microsoft/signalr/-/signalr-7.0.7.tgz#4d89bb4f0a0902c05d9dc434375c669b9d183bc8" - integrity sha512-RMWZLTxnjWPSaS9PYZxXAttql2JDM/+IsSJk0nACFhpLjnSw8UWfvUxOv/QjZSqLxhuksXxzBJ/91xUP6Y7Nvg== + version "7.0.9" + resolved "https://registry.yarnpkg.com/@microsoft/signalr/-/signalr-7.0.9.tgz#bc0ba8f38b0cb3621c5f18b56d8096190689a3ca" + integrity sha512-aGfBLAYTh+6ydYvLXV/jcocWr8KKmTOgWyl/mDx5Hzrii1aAfrn+bpBNzrl5sto5ehsHCdTIzTCuOCT3baIjOw== dependencies: abort-controller "^3.0.0" eventsource "^2.0.2" @@ -2629,6 +2620,11 @@ dependencies: eslint-scope "5.1.1" +"@nicolo-ribaudo/semver-v6@^6.3.3": + version "6.3.3" + resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/semver-v6/-/semver-v6-6.3.3.tgz#ea6d23ade78a325f7a52750aab1526b02b628c29" + integrity sha512-3Yc1fUTs69MG/uZbJlLSI3JISMn2UV2rg+1D/vROUqZyh3l6iYHCs7GMp+M40ZD7yOdDbYjJcU1oTJhrc+dGKg== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -2651,12 +2647,12 @@ fastq "^1.6.0" "@playwright/test@^1.35.1": - version "1.35.1" - resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.35.1.tgz#a596b61e15b980716696f149cc7a2002f003580c" - integrity sha512-b5YoFe6J9exsMYg0pQAobNDR85T1nLumUYgUTtKm4d21iX2L7WqKq9dW8NGJ+2vX0etZd+Y7UeuqsxDXm9+5ZA== + version "1.36.1" + resolved "https://registry.yarnpkg.com/@playwright/test/-/test-1.36.1.tgz#0b1247d279f142ac0876ce25e7daf15439d5367b" + integrity sha512-YK7yGWK0N3C2QInPU6iaf/L3N95dlGdbsezLya4n0ZCh3IL7VgPGxC6Gnznh9ApWdOmkJeleT2kMTcWPRZvzqg== dependencies: "@types/node" "*" - playwright-core "1.35.1" + playwright-core "1.36.1" optionalDependencies: fsevents "2.3.2" @@ -2960,9 +2956,9 @@ "@types/estree" "*" "@types/eslint@*", "@types/eslint@^7.29.0 || ^8.4.1": - version "8.40.2" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.40.2.tgz#2833bc112d809677864a4b0e7d1de4f04d7dac2d" - integrity sha512-PRVjQ4Eh9z9pmmtaq8nTjZjQwKFk7YIHIud3lRoKRBgUQjgjRmoGxxGEPXQkF+lH7QkHJRNr5F4aBgYCW0lqpQ== + version "8.44.0" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.0.tgz#55818eabb376e2272f77fbf5c96c43137c3c1e53" + integrity sha512-gsF+c/0XOguWgaOgvFs+xnnRqt9GwgTvIks36WpE6ueeI4KCEHHd8K/CKHqhOqrJKsYH8m27kRzQEvWXAwXUTw== dependencies: "@types/estree" "*" "@types/json-schema" "*" @@ -3079,14 +3075,14 @@ integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== "@types/node@*": - version "20.3.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe" - integrity sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg== + version "20.4.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" + integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== "@types/node@^18.11.9": - version "18.16.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.18.tgz#85da09bafb66d4bc14f7c899185336d0c1736390" - integrity sha512-/aNaQZD0+iSBAGnvvN2Cx92HqE5sZCPZtx2TsK+4nvV23fFe09jVDvpArXr2j9DnYlzuU9WuoykDDc6wqvpNcw== + version "18.16.19" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.19.tgz#cb03fca8910fdeb7595b755126a8a78144714eea" + integrity sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA== "@types/parse-json@^4.0.0": version "4.0.0" @@ -3119,16 +3115,16 @@ integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== "@types/react-dom@^18.0.11": - version "18.2.6" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.6.tgz#ad621fa71a8db29af7c31b41b2ea3d8a6f4144d1" - integrity sha512-2et4PDvg6PVCyS7fuTc4gPoksV58bW0RwSxWKcPRcHZf0PRUGq03TKcD/rUHe3azfV6/5/biUBJw+HhCQjaP0A== + version "18.2.7" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.7.tgz#67222a08c0a6ae0a0da33c3532348277c70abb63" + integrity sha512-GRaAEriuT4zp9N4p1i8BDBYmEyfo+xQ3yHjJU4eiK5NDa1RmUZG+unZABUTK4/Ox/M+GaHwb6Ow8rUITrtjszA== dependencies: "@types/react" "*" "@types/react@*", "@types/react@^18.0.28": - version "18.2.14" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.14.tgz#fa7a6fecf1ce35ca94e74874f70c56ce88f7a127" - integrity sha512-A0zjq+QN/O0Kpe30hA1GidzyFjatVvrpIvWLxD+xv67Vt91TWWgco9IvrJBkeyHm1trGaFS/FSGqPlhyeZRm0g== + version "18.2.15" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.15.tgz#14792b35df676c20ec3cf595b262f8c615a73066" + integrity sha512-oEjE7TQt1fFTFSbf8kkNuc798ahTUzn3Le67/PWjE8MAfYAD/qB7O8hSTcromLFqHCt9bcdOg5GXMokzTjJ5SA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -3229,94 +3225,94 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.5.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.0.tgz#2f4bea6a3718bed2ba52905358d0f45cd3620d31" - integrity sha512-78B+anHLF1TI8Jn/cD0Q00TBYdMgjdOn980JfAVa9yw5sop8nyTfVOQAv6LWywkOGLclDBtv5z3oxN4w7jxyNg== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== dependencies: "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.60.0" - "@typescript-eslint/type-utils" "5.60.0" - "@typescript-eslint/utils" "5.60.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" - grapheme-splitter "^1.0.4" + graphemer "^1.4.0" ignore "^5.2.0" natural-compare-lite "^1.4.0" semver "^7.3.7" tsutils "^3.21.0" "@typescript-eslint/experimental-utils@^5.0.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.60.0.tgz#48ffa47238592397c3d857fe1403eed3b1d5e604" - integrity sha512-ovid3u7CNBrr0Ct35LUPkNYH4e+z4Kc6dPfSG99oMmH9SfoEoefq09uSnJI4mUb/UM7a/peVM03G+MzLxrD16g== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz#14559bf73383a308026b427a4a6129bae2146741" + integrity sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw== dependencies: - "@typescript-eslint/utils" "5.60.0" + "@typescript-eslint/utils" "5.62.0" "@typescript-eslint/parser@^5.5.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.60.0.tgz#08f4daf5fc6548784513524f4f2f359cebb4068a" - integrity sha512-jBONcBsDJ9UoTWrARkRRCgDz6wUggmH5RpQVlt7BimSwaTkTjwypGzKORXbR4/2Hqjk9hgwlon2rVQAjWNpkyQ== + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== dependencies: - "@typescript-eslint/scope-manager" "5.60.0" - "@typescript-eslint/types" "5.60.0" - "@typescript-eslint/typescript-estree" "5.60.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" debug "^4.3.4" -"@typescript-eslint/scope-manager@5.60.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.60.0.tgz#ae511967b4bd84f1d5e179bb2c82857334941c1c" - integrity sha512-hakuzcxPwXi2ihf9WQu1BbRj1e/Pd8ZZwVTG9kfbxAMZstKz8/9OoexIwnmLzShtsdap5U/CoQGRCWlSuPbYxQ== +"@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== dependencies: - "@typescript-eslint/types" "5.60.0" - "@typescript-eslint/visitor-keys" "5.60.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" -"@typescript-eslint/type-utils@5.60.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.60.0.tgz#69b09087eb12d7513d5b07747e7d47f5533aa228" - integrity sha512-X7NsRQddORMYRFH7FWo6sA9Y/zbJ8s1x1RIAtnlj6YprbToTiQnM6vxcMu7iYhdunmoC0rUWlca13D5DVHkK2g== +"@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== dependencies: - "@typescript-eslint/typescript-estree" "5.60.0" - "@typescript-eslint/utils" "5.60.0" + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" debug "^4.3.4" tsutils "^3.21.0" -"@typescript-eslint/types@5.60.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.60.0.tgz#3179962b28b4790de70e2344465ec97582ce2558" - integrity sha512-ascOuoCpNZBccFVNJRSC6rPq4EmJ2NkuoKnd6LDNyAQmdDnziAtxbCGWCbefG1CNzmDvd05zO36AmB7H8RzKPA== +"@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== -"@typescript-eslint/typescript-estree@5.60.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.0.tgz#4ddf1a81d32a850de66642d9b3ad1e3254fb1600" - integrity sha512-R43thAuwarC99SnvrBmh26tc7F6sPa2B3evkXp/8q954kYL6Ro56AwASYWtEEi+4j09GbiNAHqYwNNZuNlARGQ== +"@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== dependencies: - "@typescript-eslint/types" "5.60.0" - "@typescript-eslint/visitor-keys" "5.60.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" debug "^4.3.4" globby "^11.1.0" is-glob "^4.0.3" semver "^7.3.7" tsutils "^3.21.0" -"@typescript-eslint/utils@5.60.0", "@typescript-eslint/utils@^5.58.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.60.0.tgz#4667c5aece82f9d4f24a667602f0f300864b554c" - integrity sha512-ba51uMqDtfLQ5+xHtwlO84vkdjrqNzOnqrnwbMHMRY8Tqeme8C2Q8Fc7LajfGR+e3/4LoYiWXUM6BpIIbHJ4hQ== +"@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.58.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@types/json-schema" "^7.0.9" "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.60.0" - "@typescript-eslint/types" "5.60.0" - "@typescript-eslint/typescript-estree" "5.60.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" eslint-scope "^5.1.1" semver "^7.3.7" -"@typescript-eslint/visitor-keys@5.60.0": - version "5.60.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.0.tgz#b48b29da3f5f31dd1656281727004589d2722a66" - integrity sha512-wm9Uz71SbCyhUKgcaPRauBdTegUyY/ZWl8gLwD/i/ybJqscrrdVSFImpvUz16BLPChIeKBK5Fa9s6KDQjsjyWw== +"@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== dependencies: - "@typescript-eslint/types" "5.60.0" + "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" "@uifabric/set-version@^7.0.24": @@ -3568,10 +3564,10 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.2.4, acorn@^8.7.1, acorn@^8.8.0, acorn@^8.8.2: - version "8.9.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.9.0.tgz#78a16e3b2bcc198c10822786fa6679e245db5b59" - integrity sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ== +acorn@^8.2.4, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" + integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== address@^1.0.1, address@^1.1.2: version "1.2.2" @@ -3785,7 +3781,7 @@ array-flatten@^2.1.2: resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== -array-includes@^3.1.5, array-includes@^3.1.6: +array-includes@^3.1.6: version "3.1.6" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.6.tgz#9e9e720e194f198266ba9e18c29e6a9b0e4b225f" integrity sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw== @@ -3843,6 +3839,18 @@ array.prototype.tosorted@^1.1.1: es-shim-unscopables "^1.0.0" get-intrinsic "^1.1.3" +arraybuffer.prototype.slice@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz#9b5ea3868a6eebc30273da577eb888381c0044bb" + integrity sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + arrify@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" @@ -3968,29 +3976,29 @@ babel-plugin-named-asset-import@^0.3.8: resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.8.tgz#6b7fa43c59229685368683c28bc9734f24524cc2" integrity sha512-WXiAc++qo7XcJ1ZnTYGtLxmBCVbddAml3CEXgWaBzNzLNoxtQ8AiGEFDMOhot9XjTCQbvP5E77Fj9Gk924f00Q== -babel-plugin-polyfill-corejs2@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.3.tgz#75044d90ba5043a5fb559ac98496f62f3eb668fd" - integrity sha512-bM3gHc337Dta490gg+/AseNB9L4YLHxq1nGKZZSHbhXv4aTYU2MD2cjza1Ru4S6975YLTaL1K8uJf6ukJhhmtw== +babel-plugin-polyfill-corejs2@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.4.tgz#9f9a0e1cd9d645cc246a5e094db5c3aa913ccd2b" + integrity sha512-9WeK9snM1BfxB38goUEv2FLnA6ja07UMfazFHzCXUb3NyDZAwfXvQiURQ6guTTMeHcOsdknULm1PDhs4uWtKyA== dependencies: - "@babel/compat-data" "^7.17.7" - "@babel/helper-define-polyfill-provider" "^0.4.0" - semver "^6.1.1" + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.1" + "@nicolo-ribaudo/semver-v6" "^6.3.3" -babel-plugin-polyfill-corejs3@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.1.tgz#39248263c38191f0d226f928d666e6db1b4b3a8a" - integrity sha512-ikFrZITKg1xH6pLND8zT14UPgjKHiGLqex7rGEZCH2EvhsneJaJPemmpQaIZV5AL03II+lXylw3UmddDK8RU5Q== +babel-plugin-polyfill-corejs3@^0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.2.tgz#d406c5738d298cd9c66f64a94cf8d5904ce4cc5e" + integrity sha512-Cid+Jv1BrY9ReW9lIfNlNpsI53N+FN7gE+f73zLAUbr9C52W4gKLWSByx47pfDJsEysojKArqOtOKZSVIIUTuQ== dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.0" - core-js-compat "^3.30.1" + "@babel/helper-define-polyfill-provider" "^0.4.1" + core-js-compat "^3.31.0" -babel-plugin-polyfill-regenerator@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.0.tgz#e7344d88d9ef18a3c47ded99362ae4a757609380" - integrity sha512-hDJtKjMLVa7Z+LwnTCxoDLQj6wdc+B8dun7ayF2fYieI6OzfuvcLMB32ihJZ4UhCBwNYGl5bg/x/P9cMdnkc2g== +babel-plugin-polyfill-regenerator@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.1.tgz#ace7a5eced6dff7d5060c335c52064778216afd3" + integrity sha512-L8OyySuI6OSQ5hFy9O+7zFjyr4WhAfRjLIOkhQGYl+emwJkd/S4XXT1JpfrgR1jrQ1NcGiOh+yAdGlF8pnC3Jw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.0" + "@babel/helper-define-polyfill-provider" "^0.4.1" babel-plugin-transform-react-remove-prop-types@^0.4.24: version "0.4.24" @@ -4196,7 +4204,7 @@ browser-process-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== -browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.3, browserslist@^4.21.4, browserslist@^4.21.5: +browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.18.1, browserslist@^4.21.4, browserslist@^4.21.5, browserslist@^4.21.9: version "4.21.9" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.9.tgz#e11bdd3c313d7e2a9e87e8b4b0c7872b13897635" integrity sha512-M0MFoZzbUrRU4KNfCrDLnvyE7gub+peetoTid3TBIqtunaDJyXlwhakT+/VkvSXcfIzFfK/nkCs4nmyTmxdNSg== @@ -4300,9 +4308,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001464, caniuse-lite@^1.0.30001503: - version "1.0.30001507" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001507.tgz#fae53f6286e7564783eadea9b447819410a59534" - integrity sha512-SFpUDoSLCaE5XYL2jfqe9ova/pbQHEmbheDf5r4diNwbAgR3qxM9NQtfsiSscjqoya5K7kFcHPUQ+VsUkIJR4A== + version "1.0.30001517" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz#90fabae294215c3495807eb24fc809e11dc2f0a8" + integrity sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA== case-sensitive-paths-webpack-plugin@^2.4.0: version "2.4.0" @@ -4355,9 +4363,9 @@ chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.2: supports-color "^7.1.0" chalk@^5.0.1: - version "5.2.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.2.0.tgz#249623b7d66869c673699fb66d65723e54dfcfb3" - integrity sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA== + version "5.3.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.3.0.tgz#67c20a7ebef70e7f3970a01f90fa210cb6860385" + integrity sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w== char-regex@^1.0.2: version "1.0.2" @@ -4480,9 +4488,9 @@ code-point-at@^1.0.0: integrity sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA== collect-v8-coverage@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz#cc2c8e94fc18bbdffe64d6534570c8a673b27f59" - integrity sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg== + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== color-convert@^1.9.0: version "1.9.3" @@ -4637,17 +4645,17 @@ cookie@0.5.0: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== -core-js-compat@^3.30.1, core-js-compat@^3.30.2: - version "3.31.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.0.tgz#4030847c0766cc0e803dcdfb30055d7ef2064bf1" - integrity sha512-hM7YCu1cU6Opx7MXNu0NuumM0ezNeAeRKadixyiQELWY3vT3De9S4J5ZBMraWV2vZnrE1Cirl0GtFtDtMUXzPw== +core-js-compat@^3.31.0: + version "3.31.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.31.1.tgz#5084ad1a46858df50ff89ace152441a63ba7aae0" + integrity sha512-wIDWd2s5/5aJSdpOJHfSibxNODxoGoWOBHt8JSPB41NOE94M7kuTPZCYLOlTtuoXTsBPKobpJ6T+y0SSy5L9SA== dependencies: - browserslist "^4.21.5" + browserslist "^4.21.9" core-js-pure@^3.23.3: - version "3.31.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.31.0.tgz#052fd9e82fbaaf86457f5db1fadcd06f15966ff2" - integrity sha512-/AnE9Y4OsJZicCzIe97JP5XoPKQJfTuEG43aEVLFJGOJpyqELod+pE6LEl63DfG1Mp8wX97LDaDpy1GmLEUxlg== + version "3.31.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.31.1.tgz#73d154958881873bc19381df80bddb20c8d0cdb5" + integrity sha512-w+C62kvWti0EPs4KPMCMVv9DriHSXfQOCQ94bGGBiEW5rrbtt/Rz8n5Krhfw9cpFyzXBjf3DB3QnPdEzGDY4Fw== core-js@^2.4.0: version "2.6.12" @@ -4655,9 +4663,9 @@ core-js@^2.4.0: integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== core-js@^3.19.2: - version "3.31.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.31.0.tgz#4471dd33e366c79d8c0977ed2d940821719db344" - integrity sha512-NIp2TQSGfR6ba5aalZD+ZQ1fSxGhDo/s1w0nx3RYzf2pnJxt7YynxFlFScP6eV7+GZsKO95NSjGxyJsU3DZgeQ== + version "3.31.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.31.1.tgz#f2b0eea9be9da0def2c5fece71064a7e5d687653" + integrity sha512-2sKLtfq1eFST7l7v62zaqXacPc7uG8ZAya8ogijLhTtaKNcpzpB4TMoTw2Si+8GYKRwFPMMtUT0263QFWFfqyQ== core-util-is@~1.0.0: version "1.0.3" @@ -4722,9 +4730,9 @@ css-blank-pseudo@^3.0.3: postcss-selector-parser "^6.0.9" css-declaration-sorter@^6.3.1: - version "6.4.0" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.0.tgz#630618adc21724484b3e9505bce812def44000ad" - integrity sha512-jDfsatwWMWN0MODAFuHszfjphEXfNw9JUAhmY4pLu3TyTU+ohUpsbVtbU+1MZn4a47D9kqh03i4eyOm+74+zew== + version "6.4.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" + integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== css-has-pseudo@^3.0.4: version "3.0.4" @@ -4971,7 +4979,7 @@ deep-extend@^0.6.0: resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== -deep-is@^0.1.3, deep-is@~0.1.3: +deep-is@^0.1.3: version "0.1.4" resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== @@ -5257,9 +5265,9 @@ ejs@^3.1.6: jake "^10.8.5" electron-to-chromium@^1.4.431: - version "1.4.440" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.440.tgz#d3b1eeb36b717eb479a240c0406ac1fa67901762" - integrity sha512-r6dCgNpRhPwiWlxbHzZQ/d9swfPaEJGi8ekqRBwQYaR3WmA5VkqQfBWSDDjuJU1ntO+W9tHx8OHV/96Q8e0dVw== + version "1.4.465" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.465.tgz#8f7a47a2a45b9b9e9a706967e47098e4d472d237" + integrity sha512-XQcuHvEJRMU97UJ75e170mgcITZoz0lIyiaVjk6R+NMTJ8KBIvUHYd1779swgOppUlzxR+JsLpq59PumaXS1jQ== emittery@^0.10.2: version "0.10.2" @@ -5319,17 +5327,18 @@ error-stack-parser@^2.0.6: stackframe "^1.3.4" es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21.2: - version "1.21.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.21.2.tgz#a56b9695322c8a185dc25975aa3b8ec31d0e7eff" - integrity sha512-y/B5POM2iBnIxCiernH1G7rC9qQoM77lLIMQLuob0zhp8C56Po81+2Nj0WFKnd0pNReDTnkYryc+zhOzpEIROg== + version "1.22.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.1.tgz#8b4e5fc5cefd7f1660f0f8e1a52900dfbc9d9ccc" + integrity sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw== dependencies: array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.1" available-typed-arrays "^1.0.5" call-bind "^1.0.2" es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" function.prototype.name "^1.1.5" - get-intrinsic "^1.2.0" + get-intrinsic "^1.2.1" get-symbol-description "^1.0.0" globalthis "^1.0.3" gopd "^1.0.1" @@ -5349,14 +5358,18 @@ es-abstract@^1.17.2, es-abstract@^1.19.0, es-abstract@^1.20.4, es-abstract@^1.21 object-inspect "^1.12.3" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.4.3" + regexp.prototype.flags "^1.5.0" + safe-array-concat "^1.0.0" safe-regex-test "^1.0.0" string.prototype.trim "^1.2.7" string.prototype.trimend "^1.0.6" string.prototype.trimstart "^1.0.6" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" - which-typed-array "^1.1.9" + which-typed-array "^1.1.10" es-array-method-boxes-properly@^1.0.0: version "1.0.0" @@ -5419,14 +5432,13 @@ escape-string-regexp@^4.0.0: integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== escodegen@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" - integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== dependencies: esprima "^4.0.1" estraverse "^5.2.0" esutils "^2.0.2" - optionator "^0.8.1" optionalDependencies: source-map "~0.6.1" @@ -5566,9 +5578,9 @@ eslint-scope@5.1.1, eslint-scope@^5.1.1: estraverse "^4.1.1" eslint-scope@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.0.tgz#f21ebdafda02352f103634b96dd47d9f81ca117b" - integrity sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw== + version "7.2.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.1.tgz#936821d3462675f25a18ac5fd88a67cc15b393bd" + integrity sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA== dependencies: esrecurse "^4.3.0" estraverse "^5.2.0" @@ -5595,14 +5607,14 @@ eslint-webpack-plugin@^3.1.1: schema-utils "^4.0.0" eslint@^8.3.0, eslint@^8.42.0: - version "8.43.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.43.0.tgz#3e8c6066a57097adfd9d390b8fc93075f257a094" - integrity sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q== + version "8.45.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.45.0.tgz#bab660f90d18e1364352c0a6b7c6db8edb458b78" + integrity sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.4.0" - "@eslint/eslintrc" "^2.0.3" - "@eslint/js" "8.43.0" + "@eslint/eslintrc" "^2.1.0" + "@eslint/js" "8.44.0" "@humanwhocodes/config-array" "^0.11.10" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -5614,7 +5626,7 @@ eslint@^8.3.0, eslint@^8.42.0: escape-string-regexp "^4.0.0" eslint-scope "^7.2.0" eslint-visitor-keys "^3.4.1" - espree "^9.5.2" + espree "^9.6.0" esquery "^1.4.2" esutils "^2.0.2" fast-deep-equal "^3.1.3" @@ -5624,7 +5636,6 @@ eslint@^8.3.0, eslint@^8.42.0: globals "^13.19.0" graphemer "^1.4.0" ignore "^5.2.0" - import-fresh "^3.0.0" imurmurhash "^0.1.4" is-glob "^4.0.0" is-path-inside "^3.0.3" @@ -5634,17 +5645,16 @@ eslint@^8.3.0, eslint@^8.42.0: lodash.merge "^4.6.2" minimatch "^3.1.2" natural-compare "^1.4.0" - optionator "^0.9.1" + optionator "^0.9.3" strip-ansi "^6.0.1" - strip-json-comments "^3.1.0" text-table "^0.2.0" -espree@^9.5.2: - version "9.5.2" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.5.2.tgz#e994e7dc33a082a7a82dceaf12883a829353215b" - integrity sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw== +espree@^9.6.0: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== dependencies: - acorn "^8.8.0" + acorn "^8.9.0" acorn-jsx "^5.3.2" eslint-visitor-keys "^3.4.1" @@ -5808,9 +5818,9 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^3.2.12, fast-glob@^3.2.9: - version "3.2.12" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.12.tgz#7f39ec99c2e6ab030337142da9e0c18f37afae80" - integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== + version "3.3.0" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.0.tgz#7c40cb491e1e2ed5664749e87bfb516dbe8727c0" + integrity sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -5823,7 +5833,7 @@ fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== -fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: +fast-levenshtein@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== @@ -6195,7 +6205,7 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0: +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== @@ -6335,11 +6345,6 @@ graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== -grapheme-splitter@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e" - integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ== - graphemer@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" @@ -6647,11 +6652,11 @@ immer@^9.0.21, immer@^9.0.7: integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== immutable@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.0.tgz#eb1738f14ffb39fd068b1dbe1296117484dd34be" - integrity sha512-0AOCmOip+xgJwEVTQj1EfiDDOkPmuyllDuTuEX+DDXUgapLAsBIfkg3sxCYyCEA8mQqZrrxPUGjcOQ2JS3WLkg== + version "4.3.1" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.3.1.tgz#17988b356097ab0719e2f741d56f3ec6c317f9dc" + integrity sha512-lj9cnmB/kVS0QHsJnYKD1uo3o39nrbKxszjnqS9Fr6NB7bZzW45U6WSGBPKXDL/CvDKqDNPA4r3DoDQ8GTxo2A== -import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1: +import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -6750,11 +6755,6 @@ invert-kv@^1.0.0: resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" integrity sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ== -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw== - ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" @@ -6956,15 +6956,11 @@ is-symbol@^1.0.2, is-symbol@^1.0.3: has-symbols "^1.0.2" is-typed-array@^1.1.10, is-typed-array@^1.1.9: - version "1.1.10" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.10.tgz#36a5b5cb4189b575d1a3e4b08536bfb485801e3f" - integrity sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A== + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" + which-typed-array "^1.1.11" is-typedarray@^1.0.0: version "1.0.0" @@ -7540,9 +7536,9 @@ jest@^27.4.3: jest-cli "^27.5.1" jiti@^1.18.2: - version "1.18.2" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.18.2.tgz#80c3ef3d486ebf2450d9335122b32d121f2a83cd" - integrity sha512-QAdOptna2NYiSSpv0O/BwoHBSmz4YhpzJHyi+fnMRTXFjp7B8i/YG5Z8IfusxB1ufjcD2Sre1F3R+nX3fvy7gg== + version "1.19.1" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.19.1.tgz#fa99e4b76a23053e0e7cde098efe1704a14c16f1" + integrity sha512-oVhqoRDaBXf7sjkll95LHVS6Myyyb1zaunVwk4Z0+WPSW4gjS0pl01zYKHScTuyEhQsFxV5L4DR5r+YqSyqyyg== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -7675,12 +7671,14 @@ jsonwebtoken@^8.1.0: semver "^5.6.0" "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz#76b3e6e6cece5c69d49a5792c3d01bd1a0cdc7ea" - integrity sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw== + version "3.3.4" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.4.tgz#b896535fed5b867650acce5a9bd4135ffc7b3bf9" + integrity sha512-fX2TVdCViod6HwKEtSWGHs57oFhVfCMwieb9PuRDgjDPh5XeqJiHFFFJCHxU5cnTc3Bu/GRL+kPiFmw8XWOfKw== dependencies: - array-includes "^3.1.5" - object.assign "^4.1.3" + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + object.assign "^4.1.4" + object.values "^1.1.6" jwa@^1.4.1: version "1.4.1" @@ -7759,14 +7757,6 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" -levn@~0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" - integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== - dependencies: - prelude-ls "~1.1.2" - type-check "~0.3.2" - lilconfig@^2.0.3, lilconfig@^2.0.5, lilconfig@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" @@ -7935,11 +7925,11 @@ magic-string@^0.25.0, magic-string@^0.25.7: sourcemap-codec "^1.4.8" magic-string@^0.30.0: - version "0.30.0" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.0.tgz#fd58a4748c5c4547338a424e90fa5dd17f4de529" - integrity sha512-LA+31JYDJLs82r2ScLrlz1GjSgu66ZV518eyWT+S8VhyQn/JL0u9MeBOvQMGYiPk1DBiSN9DDMOcXvigJZaViQ== + version "0.30.1" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.1.tgz#ce5cd4b0a81a5d032bd69aab4522299b2166284d" + integrity sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA== dependencies: - "@jridgewell/sourcemap-codec" "^1.4.13" + "@jridgewell/sourcemap-codec" "^1.4.15" make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" @@ -7978,9 +7968,9 @@ mem@^1.1.0: mimic-fn "^1.0.0" memfs@^3.1.2, memfs@^3.4.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.5.3.tgz#d9b40fe4f8d5788c5f895bda804cd0d9eeee9f3b" - integrity sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw== + version "3.6.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" + integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== dependencies: fs-monkey "^1.0.4" @@ -8013,9 +8003,9 @@ micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: picomatch "^2.3.1" microsoft-cognitiveservices-speech-sdk@^1.27.0: - version "1.29.0" - resolved "https://registry.yarnpkg.com/microsoft-cognitiveservices-speech-sdk/-/microsoft-cognitiveservices-speech-sdk-1.29.0.tgz#9feab77947301dad3dbdb19cec57137d8f502bf1" - integrity sha512-/NaDni70OR5x0FPG6LD/aOkmfLIsOwqpw0UsijcHbH+U0q6FPAX1VZVlv6ZMvkObw3k/FJv0N9CFNsN1P4M7kA== + version "1.30.1" + resolved "https://registry.yarnpkg.com/microsoft-cognitiveservices-speech-sdk/-/microsoft-cognitiveservices-speech-sdk-1.30.1.tgz#80ad5fc3a1986569881e432694099c857e5c8497" + integrity sha512-pR/abkc55hvUOG1TSmJ79Mt+A+/9R5TVeuvMaJCcvHYroIPVdG5eXqzIiZNxuy5P0x+YICYnPSOQMoHyPgtN1Q== dependencies: agent-base "^6.0.1" bent "^7.3.12" @@ -8182,9 +8172,9 @@ no-case@^3.0.4: tslib "^2.0.3" node-fetch@^2.3.0, node-fetch@^2.6.7: - version "2.6.11" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.11.tgz#cde7fc71deef3131ef80a738919f999e6edfff25" - integrity sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w== + version "2.6.12" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.12.tgz#02eb8e22074018e3d5a83016649d04df0e348fba" + integrity sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g== dependencies: whatwg-url "^5.0.0" @@ -8199,9 +8189,9 @@ node-int64@^0.4.0: integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== node-releases@^2.0.12: - version "2.0.12" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.12.tgz#35627cc224a23bfb06fb3380f2b3afaaa7eb1039" - integrity sha512-QzsYKWhXTWx8h1kIvqfnC++o0pEmpRQA/aenALsL2F4pqNVr7YzcdMlDij5WBnwftRbJCNJL/O7zdKaxKPHqgQ== + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" @@ -8252,9 +8242,9 @@ number-is-nan@^1.0.0: integrity sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ== nwsapi@^2.2.0: - version "2.2.5" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.5.tgz#a52744c61b3889dd44b0a158687add39b8d935e2" - integrity sha512-6xpotnECFy/og7tKSBVmUNft7J3jyXAka4XvG6AUhFWRz+Q/Ljus7znJAA3bxColfQLdS+XsjoodtJfCgeTEFQ== + version "2.2.7" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" + integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" @@ -8276,7 +8266,7 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== -object.assign@^4.1.3, object.assign@^4.1.4: +object.assign@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== @@ -8382,29 +8372,17 @@ opener@^1.5.1: resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598" integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A== -optionator@^0.8.1: - version "0.8.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" - integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== - dependencies: - deep-is "~0.1.3" - fast-levenshtein "~2.0.6" - levn "~0.3.0" - prelude-ls "~1.1.2" - type-check "~0.3.2" - word-wrap "~1.2.3" - -optionator@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499" - integrity sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw== +optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" deep-is "^0.1.3" fast-levenshtein "^2.0.6" levn "^0.4.1" prelude-ls "^1.2.1" type-check "^0.4.0" - word-wrap "^1.2.3" os-locale@^2.0.0: version "2.1.0" @@ -8624,10 +8602,10 @@ pkg-up@^3.1.0: dependencies: find-up "^3.0.0" -playwright-core@1.35.1: - version "1.35.1" - resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.35.1.tgz#52c1e6ffaa6a8c29de1a5bdf8cce0ce290ffb81d" - integrity sha512-pNXb6CQ7OqmGDRspEjlxE49w+4YtR6a3X6mT1hZXeJHWmsEz7SunmvZeiG/+y1yyMZdHnnn73WKYdtV1er0Xyg== +playwright-core@1.36.1: + version "1.36.1" + resolved "https://registry.yarnpkg.com/playwright-core/-/playwright-core-1.36.1.tgz#f5f275d70548768ca892583519c89b237a381c77" + integrity sha512-7+tmPuMcEW4xeCL9cp9KxmYpQYHKkyjwoXRnoeTowaeNat8PoBMk/HwCYhqkH2fRkshfKEOiVus/IhID2Pg8kg== please-upgrade-node@^3.2.0: version "3.2.0" @@ -9189,9 +9167,9 @@ postcss@^7.0.35: source-map "^0.6.1" postcss@^8.1.10, postcss@^8.3.5, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.4: - version "8.4.24" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.24.tgz#f714dba9b2284be3cc07dbd2fc57ee4dc972d2df" - integrity sha512-M0RzbcI0sO/XJNucsGjvWU9ERWxb/ytp1w6dKtxTKgixdtQDq4rmx/g8W1hnaheq9jgwL/oyEdH5Bc4WwJKMqg== + version "8.4.26" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.26.tgz#1bc62ab19f8e1e5463d98cf74af39702a00a9e94" + integrity sha512-jrXHFF8iTloAenySjM/ob3gSj7pCu0Ji49hnjqzsgSRa50hkWCKD0HQ+gMNJkW38jBI68MpAAg7ZWwHwX8NMMw== dependencies: nanoid "^3.3.6" picocolors "^1.0.0" @@ -9202,11 +9180,6 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prelude-ls@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" - integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== - prettier@^2.8.1: version "2.8.8" resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" @@ -9286,7 +9259,7 @@ pseudomap@^1.0.2: resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== -psl@^1.1.28, psl@^1.1.33: +psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== @@ -9639,7 +9612,7 @@ regex-parser@^2.2.11: resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== -regexp.prototype.flags@^1.4.3: +regexp.prototype.flags@^1.4.3, regexp.prototype.flags@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz#fe7ce25e7e4cca8db37b6634c8a2c7009199b9cb" integrity sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA== @@ -9990,24 +9963,19 @@ semver-compare@^1.0.0: integrity sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow== semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" - integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== - -semver@^6.3.1: +semver@^6.0.0, semver@^6.3.0, semver@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== semver@^7.3.2, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -10472,7 +10440,7 @@ strip-final-newline@^2.0.0: resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: +strip-json-comments@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== @@ -10500,15 +10468,15 @@ stylis@^3.5.4: resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe" integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q== -stylis@^4.0.13: - version "4.2.0" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" - integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== +stylis@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.3.0.tgz#abe305a669fc3d8777e10eefcfc73ad861c5588c" + integrity sha512-E87pIogpwUsUwXw7dNyU4QDjdgVMy52m+XEOPEKUn161cCzWjjhPSQhByfd1CcNvrOLnXQ6OnnZDwnJrz/Z4YQ== sucrase@^3.32.0: - version "3.32.0" - resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.32.0.tgz#c4a95e0f1e18b6847127258a75cf360bc568d4a7" - integrity sha512-ydQOU34rpSyj2TGyz4D2p8rbktIOZ8QY9s+DGLvFU1i5pWJE8vkpruCjGCMHsdXwnD7JDcS+noSwM/a7zyNFDQ== + version "3.34.0" + resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f" + integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw== dependencies: "@jridgewell/gen-mapping" "^0.3.2" commander "^4.0.0" @@ -10600,17 +10568,17 @@ symbol-tree@^3.2.4: integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== tabster@^4.5.1: - version "4.6.0" - resolved "https://registry.yarnpkg.com/tabster/-/tabster-4.6.0.tgz#3971e9d382d19eed5b13e4dfcff8ad2ff3004af4" - integrity sha512-JTgjk0dPKjK3cfG3ZZVcLYnsZQAaK7cx6E8LpCNzCxrcKmPVVVtwrskUtX8oQqCnk7H1X36oxRRFlbJGGThLtw== + version "4.7.0" + resolved "https://registry.yarnpkg.com/tabster/-/tabster-4.7.0.tgz#0c12e9e14e83a950e3a97e35ead17c255e8f2772" + integrity sha512-8+arpE2WOvhdU2bvU5GEaoaICbLBNNh8WhW9q85KeSOg4sIvRPfAI2/j18UxUnKT8Fv32zkbvEfToEf9Y1Sfug== dependencies: keyborg "^2.0.0" tslib "^2.3.1" tailwindcss@^3.0.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.2.tgz#2f9e35d715fdf0bbf674d90147a0684d7054a2d3" - integrity sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w== + version "3.3.3" + resolved "https://registry.yarnpkg.com/tailwindcss/-/tailwindcss-3.3.3.tgz#90da807393a2859189e48e9e7000e6880a736daf" + integrity sha512-A0KgSkef7eE4Mf+nKJ83i75TMyq8HqY3qmFIJSWy8bNt0v1lG7jUcpGpoTFxAwYcWOphcTBLPPJg+bDfhDf52w== dependencies: "@alloc/quick-lru" "^5.2.0" arg "^5.0.2" @@ -10632,7 +10600,6 @@ tailwindcss@^3.0.2: postcss-load-config "^4.0.1" postcss-nested "^6.0.1" postcss-selector-parser "^6.0.11" - postcss-value-parser "^4.2.0" resolve "^1.22.2" sucrase "^3.32.0" @@ -10681,9 +10648,9 @@ terser-webpack-plugin@^5.2.5, terser-webpack-plugin@^5.3.7: terser "^5.16.8" terser@^5.0.0, terser@^5.10.0, terser@^5.16.8: - version "5.18.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.18.1.tgz#6d8642508ae9fb7b48768e48f16d675c89a78460" - integrity sha512-j1n0Ao919h/Ai5r43VAnfV/7azUYW43GPxK7qSATzrsERfW7+y2QW9Cp9ufnRF5CQUWbnLSo7UJokSWCqg4tsQ== + version "5.19.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.1.tgz#dbd7231f224a9e2401d0f0959542ed74d76d340b" + integrity sha512-27hxBUVdV6GoNg1pKQ7Z5cbR6V9txPVyBA+FQw3BaZ1Wuzvztce5p156DaP0NVZNrMZZ+6iG9Syf7WgMNKDg2Q== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -10755,15 +10722,6 @@ toidentifier@1.0.1: resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== -tough-cookie@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-3.0.1.tgz#9df4f57e739c26930a018184887f4adb7dca73b2" - integrity sha512-yQyJ0u4pZsv9D4clxO69OEjLWYw+jbgspjTue4lTQZLfV0c5l1VmK2y1JK8E9ahdpltPOaAThPcp5nKPUgSnsg== - dependencies: - ip-regex "^2.1.0" - psl "^1.1.28" - punycode "^2.1.1" - tough-cookie@^4.0.0: version "4.1.3" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" @@ -10819,9 +10777,9 @@ tslib@^1.10.0, tslib@^1.8.1: integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== tslib@^2.0.3, tslib@^2.1.0, tslib@^2.2.0, tslib@^2.3.1, tslib@^2.4.0: - version "2.5.3" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913" - integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== + version "2.6.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.0.tgz#b295854684dbda164e181d259a22cd779dcd7bc3" + integrity sha512-7At1WUettjcSRHXCyYtTselblcHl9PJFFVKiCAy/bY97+BPZXSQ2wbq0P9s8tK2G7dFQfNnlJnPAiArVBVBsfA== tsutils@^3.21.0: version "3.21.0" @@ -10842,13 +10800,6 @@ type-check@^0.4.0, type-check@~0.4.0: dependencies: prelude-ls "^1.2.1" -type-check@~0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" - integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== - dependencies: - prelude-ls "~1.1.2" - type-detect@4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" @@ -10882,6 +10833,36 @@ type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" +typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + +typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + +typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + typed-array-length@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" @@ -11213,9 +11194,9 @@ webpack-sources@^3.2.3: integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== webpack@^5.64.4: - version "5.88.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.0.tgz#a07aa2f8e7a64a8f1cec0c6c2e180e3cb34440c8" - integrity sha512-O3jDhG5e44qIBSi/P6KpcCcH7HD+nYIHVBhdWFxcLOcIGN8zGo5nqF3BjyNCxIh4p1vFdNnreZv2h2KkoAw3lw== + version "5.88.2" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e" + integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^1.0.0" @@ -11271,9 +11252,9 @@ whatwg-encoding@^2.0.0: iconv-lite "0.6.3" whatwg-fetch@^3.6.2: - version "3.6.2" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" - integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + version "3.6.16" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.16.tgz#2cf24cd621459be8137f9e3c6afb60262d78f963" + integrity sha512-83avoGbZ0qtjtNrU3UTT3/Xd3uZ7DyfSYLuc1fL5iYs+93P+UkIVF6/6xpRVWeQcvbc7kSnVybSAVbd6QFW5Fg== whatwg-mimetype@^2.3.0: version "2.3.0" @@ -11322,17 +11303,16 @@ which-module@^2.0.0: resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.1.tgz#776b1fe35d90aebe99e8ac15eb24093389a4a409" integrity sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ== -which-typed-array@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.9.tgz#307cf898025848cf995e795e8423c7f337efbde6" - integrity sha512-w9c4xkx6mPidwp7180ckYWfMmvxpjlZuIudNtDf4N/tTAUB8VJbX25qZoAsrtGuYNnGw3pa0AXgbGKRB8/EceA== +which-typed-array@^1.1.10, which-typed-array@^1.1.11: + version "1.1.11" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" + integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== dependencies: available-typed-arrays "^1.0.5" call-bind "^1.0.2" for-each "^0.3.3" gopd "^1.0.1" has-tostringtag "^1.0.0" - is-typed-array "^1.1.10" which@^1.2.9, which@^1.3.1: version "1.3.1" @@ -11355,11 +11335,6 @@ widest-line@^4.0.1: dependencies: string-width "^5.0.1" -word-wrap@^1.2.3, word-wrap@~1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" - integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== - workbox-background-sync@6.6.1: version "6.6.1" resolved "https://registry.yarnpkg.com/workbox-background-sync/-/workbox-background-sync-6.6.1.tgz#08d603a33717ce663e718c30cc336f74909aff2f" From fae4f2e77f9ec7f3644038194ee50a1e0ec40837 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 15:17:23 -0700 Subject: [PATCH 002/582] Bump workbox-window from 6.6.1 to 7.0.0 in /webapp (#9) Bumps [workbox-window](https://github.com/googlechrome/workbox) from 6.6.1 to 7.0.0. - [Release notes](https://github.com/googlechrome/workbox/releases) - [Commits](https://github.com/googlechrome/workbox/commits/v7.0.0) --- updated-dependencies: - dependency-name: workbox-window dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ben Thomas --- webapp/package.json | 2 +- webapp/yarn.lock | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index e7b833af5..82b7148a3 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -48,7 +48,7 @@ "serve": "^14.2.0", "typescript": "5.0.4", "vsts-npm-auth": "^0.42.1", - "workbox-window": "^6.5.4" + "workbox-window": "^7.0.0" }, "eslintConfig": { "extends": [ diff --git a/webapp/yarn.lock b/webapp/yarn.lock index f76d4f561..445429ceb 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -11405,6 +11405,11 @@ workbox-core@6.6.1: resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-6.6.1.tgz#7184776d4134c5ed2f086878c882728fc9084265" integrity sha512-ZrGBXjjaJLqzVothoE12qTbVnOAjFrHDXpZe7coCb6q65qI/59rDLwuFMO4PcZ7jcbxY+0+NhUVztzR/CbjEFw== +workbox-core@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-core/-/workbox-core-7.0.0.tgz#dec114ec923cc2adc967dd9be1b8a0bed50a3545" + integrity sha512-81JkAAZtfVP8darBpfRTovHg8DGAVrKFgHpOArZbdFd78VqHr5Iw65f2guwjE2NlCFbPFDoez3D3/6ZvhI/rwQ== + workbox-expiration@6.6.1: version "6.6.1" resolved "https://registry.yarnpkg.com/workbox-expiration/-/workbox-expiration-6.6.1.tgz#a841fa36676104426dbfb9da1ef6a630b4f93739" @@ -11496,7 +11501,7 @@ workbox-webpack-plugin@^6.4.1: webpack-sources "^1.4.3" workbox-build "6.6.1" -workbox-window@6.6.1, workbox-window@^6.5.4: +workbox-window@6.6.1: version "6.6.1" resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-6.6.1.tgz#f22a394cbac36240d0dadcbdebc35f711bb7b89e" integrity sha512-wil4nwOY58nTdCvif/KEZjQ2NP8uk3gGeRNy2jPBbzypU4BT4D9L8xiwbmDBpZlSgJd2xsT9FvSNU0gsxV51JQ== @@ -11504,6 +11509,14 @@ workbox-window@6.6.1, workbox-window@^6.5.4: "@types/trusted-types" "^2.0.2" workbox-core "6.6.1" +workbox-window@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/workbox-window/-/workbox-window-7.0.0.tgz#a683ab33c896e4f16786794eac7978fc98a25d08" + integrity sha512-j7P/bsAWE/a7sxqTzXo3P2ALb1reTfZdvVp6OJ/uLr/C2kZAMvjeWGm8V4htQhor7DOvYg0sSbFN2+flT5U0qA== + dependencies: + "@types/trusted-types" "^2.0.2" + workbox-core "7.0.0" + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" From 7416c1be8770866467d43d25de2afc4aa235f490 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 15:33:50 -0700 Subject: [PATCH 003/582] Bump Microsoft.Azure.Cosmos from 3.34.0 to 3.35.2 in /webapi (#4) Bumps [Microsoft.Azure.Cosmos](https://github.com/Azure/azure-cosmos-dotnet-v3) from 3.34.0 to 3.35.2. - [Release notes](https://github.com/Azure/azure-cosmos-dotnet-v3/releases) - [Changelog](https://github.com/Azure/azure-cosmos-dotnet-v3/blob/master/changelog.md) - [Commits](https://github.com/Azure/azure-cosmos-dotnet-v3/compare/3.34.0...3.35.2) --- updated-dependencies: - dependency-name: Microsoft.Azure.Cosmos dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ben Thomas --- webapi/CopilotChatWebApi.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapi/CopilotChatWebApi.csproj b/webapi/CopilotChatWebApi.csproj index 48b634cc9..38a37ac82 100644 --- a/webapi/CopilotChatWebApi.csproj +++ b/webapi/CopilotChatWebApi.csproj @@ -10,7 +10,7 @@ - + From 93fe954468a23cc791daa9303d8b72ac8e4e60ba Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Jul 2023 15:41:07 -0700 Subject: [PATCH 004/582] Bump Microsoft.Identity.Web from 2.11.1 to 2.13.0 in /webapi (#3) Bumps [Microsoft.Identity.Web](https://github.com/AzureAD/microsoft-identity-web) from 2.11.1 to 2.13.0. - [Release notes](https://github.com/AzureAD/microsoft-identity-web/releases) - [Changelog](https://github.com/AzureAD/microsoft-identity-web/blob/master/changelog.md) - [Commits](https://github.com/AzureAD/microsoft-identity-web/compare/2.11.1...2.13.0) --- updated-dependencies: - dependency-name: Microsoft.Identity.Web dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Ben Thomas --- webapi/CopilotChatWebApi.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapi/CopilotChatWebApi.csproj b/webapi/CopilotChatWebApi.csproj index 38a37ac82..964e845d1 100644 --- a/webapi/CopilotChatWebApi.csproj +++ b/webapi/CopilotChatWebApi.csproj @@ -20,7 +20,7 @@ - + From a538b6c090054731e3058f0147d71343cee13333 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Thu, 20 Jul 2023 14:31:13 -0700 Subject: [PATCH 005/582] Updating main README to link to semantic-kernel repo and rename copilot chat to chat copilot. (#11) Co-authored-by: Ben Thomas --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 7d60cd93d..bb20fc54b 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ > This sample is for educational purposes only and is not recommended for production deployments. -# About Copilot Chat +# About Chat Copilot -This sample allows you to build your own integrated large language model chat copilot. +This sample allows you to build your own integrated large language model chat copilot that is powered by [semantic-kernel](https://github.com/microsoft/semantic-kernel). This is an enriched intelligence app, with multiple dynamic components including command messages, user intent, and memories. @@ -153,7 +153,7 @@ to the back end while waiting for your permission to connect. To resolve this, t 2. If your browser asks you to acknowledge the risks of visiting an insecure website, you must acknowledge the message before the front end will be allowed to connect to the back-end server. - Acknowledge, continue, and navigate until you see the message `Healthy`. -3. Navigate to `http://localhost:3000` or refresh the page to use the Copilot Chat application. +3. Navigate to `http://localhost:3000` or refresh the page to use the Chat Copilot application. ## 4. Have Yarn version 2.x or 3.x From f67f293cb1ec910b9358547261717d35f834495c Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Fri, 21 Jul 2023 14:11:52 -0700 Subject: [PATCH 006/582] Disable alwaysOn and enable health check (#13) ### Motivation and Context Addressing issue: https://github.com/microsoft/semantic-kernel/issues/1702 ### Description Instead of mapping / to /healthz, we decided to disable alwaysOn and enable App Service health check. This is because mapping / to /healthz creates a dependency on the deployment setup and makes the code harder to maintain, i.e when alwaysOn is disabled, there is really not point at mapping the route. Thus, disabling alwaysOn and enabling App service health check is a cleaner solution. ### Contribution Checklist - [ ] The code builds clean without any errors or warnings - [ ] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone :smile: --- deploy/main.bicep | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/deploy/main.bicep b/deploy/main.bicep index 7307dea84..f60caeaff 100644 --- a/deploy/main.bicep +++ b/deploy/main.bicep @@ -134,6 +134,9 @@ resource appServiceWeb 'Microsoft.Web/sites@2022-09-01' = { serverFarmId: appServicePlan.id httpsOnly: true virtualNetworkSubnetId: virtualNetwork.properties.subnets[0].id + siteConfig: { + healthCheckPath: '/healthz' + } } } @@ -141,7 +144,7 @@ resource appServiceWebConfig 'Microsoft.Web/sites/config@2022-09-01' = { parent: appServiceWeb name: 'web' properties: { - alwaysOn: true + alwaysOn: false cors: { allowedOrigins: [ 'http://localhost:3000' From 61a6b05e4cb3c1e7969cbaea631adc4548421573 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Fri, 21 Jul 2023 17:03:46 -0700 Subject: [PATCH 007/582] Copilot CI/CD pipeline (#15) ### Motivation and Context Continuous deployment and verification will help us maintain the quality of Chat Copilot and ensure that it remains functional and deployable to Azure. ### Description - Created workflow to deploy to two Azure hosted environments. The first deployment to `int` happens automatically after a merge to the main branch where scenario tests will be run. The second deployment to `stable` will happen when approved by the team and after all testing and verifications have successfully passed in `int`. - Updates deployment scripts to allow the Client Authority to be specified which allows us to restrict authentication in the app to members of a specific tenant, Microsoft in the case of this pipeline. - Several fixes in the various deployment scripts, .ps and .sh. ### Contribution Checklist - [x] The code builds clean without any errors or warnings - [x] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone :smile: --------- Co-authored-by: Ben Thomas --- .github/workflows/copilot-build.yml | 53 +++++++++++++ .github/workflows/copilot-deploy-backend.yml | 76 +++++++++++++++++++ .../workflows/copilot-deploy-environment.yml | 64 ++++++++++++++++ .github/workflows/copilot-deploy-frontend.yml | 74 ++++++++++++++++++ .github/workflows/copilot-deploy-infra.yml | 63 +++++++++++++++ .github/workflows/copilot-deploy-pipeline.yml | 42 ++++++++++ deploy/deploy-azure.ps1 | 12 ++- deploy/deploy-azure.sh | 21 ++++- deploy/deploy-webapi.sh | 12 +-- deploy/deploy-webapp.ps1 | 9 ++- deploy/deploy-webapp.sh | 62 ++++++++++----- deploy/main.bicep | 26 +++---- deploy/main.json | 14 +++- deploy/package-webapi.sh | 2 +- webapp/src/components/views/BackendProbe.tsx | 2 +- 15 files changed, 477 insertions(+), 55 deletions(-) create mode 100644 .github/workflows/copilot-build.yml create mode 100644 .github/workflows/copilot-deploy-backend.yml create mode 100644 .github/workflows/copilot-deploy-environment.yml create mode 100644 .github/workflows/copilot-deploy-frontend.yml create mode 100644 .github/workflows/copilot-deploy-infra.yml create mode 100644 .github/workflows/copilot-deploy-pipeline.yml mode change 100644 => 100755 deploy/deploy-azure.sh mode change 100644 => 100755 deploy/deploy-webapi.sh mode change 100644 => 100755 deploy/deploy-webapp.sh diff --git a/.github/workflows/copilot-build.yml b/.github/workflows/copilot-build.yml new file mode 100644 index 000000000..7f88f2080 --- /dev/null +++ b/.github/workflows/copilot-build.yml @@ -0,0 +1,53 @@ +name: copilot-build + +on: + workflow_call: + outputs: + artifact: + description: "The name of the uploaded artifact." + value: ${{jobs.web-api.outputs.artifact}} + +permissions: + contents: read + +jobs: + web-api: + strategy: + fail-fast: false + matrix: + include: + - { dotnet: "6.0", configuration: Release, os: windows-latest } + + runs-on: ${{ matrix.os }} + + env: + NUGET_CERT_REVOCATION_MODE: offline + + outputs: + artifact: ${{steps.artifactoutput.outputs.artifactname}} + + steps: + - uses: actions/checkout@v3 + with: + clean: true + + - name: Package Copilot Chat WebAPI + run: | + deploy\package-webapi.ps1 -Configuration Release -DotnetFramework net6.0 -TargetRuntime win-x64 -OutputDirectory ${{ github.workspace }}\deploy + + - name: Set version tag + id: versiontag + run: | + $VERSION_TAG="$(Get-Date -Format "MMddHHmmss")" + echo $VERSION_TAG + Write-Output "versiontag=$VERSION_TAG" >> $env:GITHUB_OUTPUT + + - name: Upload package to artifacts + uses: actions/upload-artifact@v3 + with: + name: copilotchat-webapi-${{ steps.versiontag.outputs.versiontag }} + path: ${{ github.workspace }}\deploy\out\webapi.zip + + - name: "Set outputs" + id: artifactoutput + run: Write-Output "artifactname=copilotchat-webapi-${{ steps.versiontag.outputs.versiontag }}" >> $env:GITHUB_OUTPUT diff --git a/.github/workflows/copilot-deploy-backend.yml b/.github/workflows/copilot-deploy-backend.yml new file mode 100644 index 000000000..30c599c9a --- /dev/null +++ b/.github/workflows/copilot-deploy-backend.yml @@ -0,0 +1,76 @@ +name: copilot-deploy-backend + +on: + workflow_call: + inputs: + ARTIFACT_NAME: + required: true + type: string + ENVIRONMENT: + required: true + type: string + DEPLOYMENT_NAME: + required: true + type: string + secrets: + AZURE_CLIENT_ID: + required: true + AZURE_TENANT_ID: + required: true + AZURE_SUBSCRIPTION_ID: + required: true + +permissions: + contents: read + +jobs: + web-api: + environment: ${{inputs.ENVIRONMENT}} + permissions: + id-token: write + strategy: + fail-fast: false + matrix: + include: + - { dotnet: "6.0", configuration: Release, os: ubuntu-latest } + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + with: + clean: true + + - uses: actions/download-artifact@v3 + with: + name: ${{inputs.ARTIFACT_NAME}} + path: "${{ github.workspace }}/${{inputs.ARTIFACT_NAME}}" + + - name: "Display downloaded content" + run: ls -R + working-directory: "${{ github.workspace }}/${{inputs.ARTIFACT_NAME}}" + + - name: Azure login + uses: azure/login@v1 + with: + client-id: ${{secrets.AZURE_CLIENT_ID}} + tenant-id: ${{secrets.AZURE_TENANT_ID}} + subscription-id: ${{secrets.AZURE_SUBSCRIPTION_ID}} + enable-AzPSSession: false + + - name: Get app name + run: | + WEB_APP_NAME=$(az deployment group show --name ${{inputs.DEPLOYMENT_NAME}} --resource-group ${{vars.CC_DEPLOYMENT_GROUP_NAME}} --output json | jq -r '.properties.outputs.webapiName.value') + echo "AZURE_WEBAPP_NAME=$WEB_APP_NAME" >> $GITHUB_ENV + + - name: Enable Run From Package + uses: azure/CLI@v1 + with: + azcliversion: 2.30.0 + inlineScript: | + az webapp config appsettings set --resource-group ${{vars.CC_DEPLOYMENT_GROUP_NAME}} --name ${{ env.AZURE_WEBAPP_NAME }} --settings WEBSITE_RUN_FROM_PACKAGE="1" + + - name: "Deploy" + uses: azure/webapps-deploy@v2 + with: + app-name: ${{ env.AZURE_WEBAPP_NAME }} + package: "${{ github.workspace }}/${{inputs.ARTIFACT_NAME}}/webapi.zip" diff --git a/.github/workflows/copilot-deploy-environment.yml b/.github/workflows/copilot-deploy-environment.yml new file mode 100644 index 000000000..a8665718f --- /dev/null +++ b/.github/workflows/copilot-deploy-environment.yml @@ -0,0 +1,64 @@ +name: copilot-deploy-environment + +on: + workflow_call: + inputs: + ENVIRONMENT: + required: true + type: string + ARTIFACT_NAME: + required: true + type: string + secrets: + AZURE_CLIENT_ID: + required: true + AZURE_TENANT_ID: + required: true + AZURE_SUBSCRIPTION_ID: + required: true + WEB_API_KEY: + required: true + AZURE_OPENAI_ENDPOINT: + required: true + APPLICATION_AUTHORITY: + required: true + +permissions: + contents: read + id-token: write + +jobs: + deploy-infra: + uses: ./.github/workflows/copilot-deploy-infra.yml + with: + ENVIRONMENT: ${{inputs.ENVIRONMENT}} + secrets: + AZURE_CLIENT_ID: ${{secrets.AZURE_CLIENT_ID}} + AZURE_TENANT_ID: ${{secrets.AZURE_TENANT_ID}} + AZURE_SUBSCRIPTION_ID: ${{secrets.AZURE_SUBSCRIPTION_ID}} + WEB_API_KEY: ${{secrets.WEB_API_KEY}} + AZURE_OPENAI_ENDPOINT: ${{secrets.AZURE_OPENAI_ENDPOINT}} + + deploy-backend: + needs: [deploy-infra] + uses: ./.github/workflows/copilot-deploy-backend.yml + with: + ARTIFACT_NAME: ${{inputs.ARTIFACT_NAME}} + DEPLOYMENT_NAME: ${{needs.deploy-infra.outputs.deployment-id}} + ENVIRONMENT: ${{inputs.ENVIRONMENT}} + secrets: + AZURE_CLIENT_ID: ${{secrets.AZURE_CLIENT_ID}} + AZURE_TENANT_ID: ${{secrets.AZURE_TENANT_ID}} + AZURE_SUBSCRIPTION_ID: ${{secrets.AZURE_SUBSCRIPTION_ID}} + + deploy-frontend: + needs: [deploy-infra] + uses: ./.github/workflows/copilot-deploy-frontend.yml + with: + DEPLOYMENT_NAME: ${{needs.deploy-infra.outputs.deployment-id}} + ENVIRONMENT: ${{inputs.ENVIRONMENT}} + secrets: + AZURE_CLIENT_ID: ${{secrets.AZURE_CLIENT_ID}} + AZURE_TENANT_ID: ${{secrets.AZURE_TENANT_ID}} + AZURE_SUBSCRIPTION_ID: ${{secrets.AZURE_SUBSCRIPTION_ID}} + APPLICATION_AUTHORITY: ${{secrets.APPLICATION_AUTHORITY}} diff --git a/.github/workflows/copilot-deploy-frontend.yml b/.github/workflows/copilot-deploy-frontend.yml new file mode 100644 index 000000000..532ba8784 --- /dev/null +++ b/.github/workflows/copilot-deploy-frontend.yml @@ -0,0 +1,74 @@ +name: copilot-deploy-backend + +on: + workflow_call: + inputs: + ENVIRONMENT: + required: true + type: string + DEPLOYMENT_NAME: + required: true + type: string + secrets: + AZURE_CLIENT_ID: + required: true + AZURE_TENANT_ID: + required: true + AZURE_SUBSCRIPTION_ID: + required: true + APPLICATION_AUTHORITY: + required: true + +permissions: + contents: read + +jobs: + web-app: + environment: ${{inputs.ENVIRONMENT}} + permissions: + id-token: write + strategy: + fail-fast: false + matrix: + include: + - { dotnet: "6.0", configuration: Release, os: ubuntu-latest } + + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + with: + clean: true + + - name: Install Azure CLI + run: | + sudo apt update && sudo apt-get install curl -y + curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash + + - name: Install Keyring + run: | + sudo apt-get install gnome-keyring -y + + - name: "Install SWA CLI" + run: npm install -g @azure/static-web-apps-cli + + - name: Azure login + uses: azure/login@v1 + with: + client-id: ${{secrets.AZURE_CLIENT_ID}} + tenant-id: ${{secrets.AZURE_TENANT_ID}} + subscription-id: ${{secrets.AZURE_SUBSCRIPTION_ID}} + enable-AzPSSession: false + + - name: "Get and Mask SWA Deployment Token" + uses: azure/CLI@v1 + with: + azcliversion: 2.30.0 + inlineScript: | + webappName=$(az deployment group show --name ${{inputs.DEPLOYMENT_NAME}} --resource-group ${{vars.CC_DEPLOYMENT_GROUP_NAME}} --output json | jq -r '.properties.outputs.webappName.value') + swaToken=$(az staticwebapp secrets list --name "$webappName" --resource-group ${{vars.CC_DEPLOYMENT_GROUP_NAME}} --query "properties.apiKey" --output json | jq -r) + echo "::add-mask::$swaToken" + echo "SWA_CLI_DEPLOYMENT_TOKEN=$swaToken" >> $GITHUB_ENV + + - name: Deploy SWA + run: | + deploy/deploy-webapp.sh --subscription ${{secrets.AZURE_SUBSCRIPTION_ID}} --resource-group ${{vars.CC_DEPLOYMENT_GROUP_NAME}} --deployment-name ${{inputs.DEPLOYMENT_NAME}} --application-id ${{vars.APPLICATION_CLIENT_ID}} --authority ${{secrets.APPLICATION_AUTHORITY}} --no-redirect diff --git a/.github/workflows/copilot-deploy-infra.yml b/.github/workflows/copilot-deploy-infra.yml new file mode 100644 index 000000000..5c608a224 --- /dev/null +++ b/.github/workflows/copilot-deploy-infra.yml @@ -0,0 +1,63 @@ +name: copilot-deploy-infra + +on: + workflow_call: + inputs: + ENVIRONMENT: + required: true + type: string + secrets: + AZURE_CLIENT_ID: + required: true + AZURE_TENANT_ID: + required: true + AZURE_SUBSCRIPTION_ID: + required: true + WEB_API_KEY: + required: true + AZURE_OPENAI_ENDPOINT: + required: true + outputs: + deployment-id: + description: "The Id of the current deployment." + value: ${{jobs.deploy.outputs.deployment-id}} + +jobs: + deploy: + environment: ${{inputs.ENVIRONMENT}} + permissions: + contents: read + id-token: write + strategy: + fail-fast: false + matrix: + include: + - { dotnet: "6.0", configuration: Release, os: ubuntu-latest } + outputs: + deployment-id: ${{steps.deployment-id.outputs.deployment_name}} + + runs-on: ${{ matrix.os }} + steps: + - name: Generate Deployment Id + id: deployment-id + run: echo "deployment_name=${{ vars.CC_DEPLOYMENT_NAME }}-$(date +'%Y-%m-%dT%H-%M-%S')" >> $GITHUB_OUTPUT + + - uses: actions/checkout@v3 + with: + clean: true + + - name: Azure login + uses: azure/login@v1 + with: + client-id: ${{secrets.AZURE_CLIENT_ID}} + tenant-id: ${{secrets.AZURE_TENANT_ID}} + subscription-id: ${{secrets.AZURE_SUBSCRIPTION_ID}} + enable-AzPSSession: false + + - name: deploy-infra + uses: azure/CLI@v1 + with: + azcliversion: 2.30.0 + inlineScript: | + AI_SERVICE_KEY=$(az cognitiveservices account keys list --name ${{vars.AZUREOPENAI__NAME}} --resource-group ${{vars.AZUREOPENAI_DEPLOYMENT_GROUP_NAME}} | jq -r '.key1') + deploy/deploy-azure.sh --subscription ${{secrets.AZURE_SUBSCRIPTION_ID}} --web-api-key ${{secrets.WEB_API_KEY}} --resource-group ${{vars.CC_DEPLOYMENT_GROUP_NAME}} --deployment-name ${{steps.deployment-id.outputs.deployment_name}} --region ${{vars.CC_DEPLOYMENT_REGION}} --ai-service AzureOpenAI --ai-endpoint ${{secrets.AZURE_OPENAI_ENDPOINT}} --ai-service-key $AI_SERVICE_KEY --app-service-sku ${{vars.WEBAPP_API_SKU}} --no-deploy-package --debug-deployment diff --git a/.github/workflows/copilot-deploy-pipeline.yml b/.github/workflows/copilot-deploy-pipeline.yml new file mode 100644 index 000000000..f4a88e4af --- /dev/null +++ b/.github/workflows/copilot-deploy-pipeline.yml @@ -0,0 +1,42 @@ +name: copilot-deploy-pipeline + +on: + workflow_dispatch: + push: + branches: ["main"] + +permissions: + contents: read + id-token: write + +jobs: + build: + uses: ./.github/workflows/copilot-build.yml + + int: + needs: build + uses: ./.github/workflows/copilot-deploy-environment.yml + with: + ENVIRONMENT: int + ARTIFACT_NAME: ${{needs.build.outputs.artifact}} + secrets: + AZURE_CLIENT_ID: ${{secrets.AZURE_CLIENT_ID}} + AZURE_TENANT_ID: ${{secrets.AZURE_TENANT_ID}} + AZURE_SUBSCRIPTION_ID: ${{secrets.AZURE_SUBSCRIPTION_ID}} + WEB_API_KEY: ${{secrets.WEB_API_KEY}} + AZURE_OPENAI_ENDPOINT: ${{secrets.AZURE_OPENAI_ENDPOINT}} + APPLICATION_AUTHORITY: ${{secrets.APPLICATION_AUTHORITY}} + + stable: + uses: ./.github/workflows/copilot-deploy-environment.yml + needs: [build, int] + with: + ENVIRONMENT: stable + ARTIFACT_NAME: ${{needs.build.outputs.artifact}} + secrets: + AZURE_CLIENT_ID: ${{secrets.AZURE_CLIENT_ID}} + AZURE_TENANT_ID: ${{secrets.AZURE_TENANT_ID}} + AZURE_SUBSCRIPTION_ID: ${{secrets.AZURE_SUBSCRIPTION_ID}} + WEB_API_KEY: ${{secrets.WEB_API_KEY}} + AZURE_OPENAI_ENDPOINT: ${{secrets.AZURE_OPENAI_ENDPOINT}} + APPLICATION_AUTHORITY: ${{secrets.APPLICATION_AUTHORITY}} diff --git a/deploy/deploy-azure.ps1 b/deploy/deploy-azure.ps1 index 487f3619f..a2757412a 100644 --- a/deploy/deploy-azure.ps1 +++ b/deploy/deploy-azure.ps1 @@ -15,7 +15,7 @@ param( $Subscription, [Parameter(Mandatory)] - [ValidateSet("AzureOpenAI","OpenAI")] + [ValidateSet("AzureOpenAI", "OpenAI")] [string] # AI service to use $AIService, @@ -84,7 +84,6 @@ if ($AIService -eq "OpenAI" -and !$AIApiKey) { $jsonConfig = " { - `\`"name`\`": { `\`"value`\`": `\`"$DeploymentName`\`" }, `\`"webAppServiceSku`\`": { `\`"value`\`": `\`"$WebAppServiceSku`\`" }, `\`"aiService`\`": { `\`"value`\`": `\`"$AIService`\`" }, `\`"aiApiKey`\`": { `\`"value`\`": `\`"$AIApiKey`\`" }, @@ -96,14 +95,13 @@ $jsonConfig = " } " -$jsonConfig = $jsonConfig -replace '\s','' +$jsonConfig = $jsonConfig -replace '\s', '' $ErrorActionPreference = "Stop" $templateFile = "$($PSScriptRoot)/main.bicep" -if (!$ResourceGroup) -{ +if (!$ResourceGroup) { $ResourceGroup = "rg-" + $DeploymentName } @@ -115,13 +113,13 @@ if ($LASTEXITCODE -ne 0) { az account set -s $Subscription if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE + exit $LASTEXITCODE } Write-Host "Ensuring resource group '$ResourceGroup' exists..." az group create --location $Region --name $ResourceGroup --tags Creator=$env:UserName if ($LASTEXITCODE -ne 0) { - exit $LASTEXITCODE + exit $LASTEXITCODE } Write-Host "Validating template file..." diff --git a/deploy/deploy-azure.sh b/deploy/deploy-azure.sh old mode 100644 new mode 100755 index 6e6999159..d5a2f639c --- a/deploy/deploy-azure.sh +++ b/deploy/deploy-azure.sh @@ -10,6 +10,7 @@ usage() { echo "Arguments:" echo " -d, --deployment-name DEPLOYMENT_NAME Name for the deployment (mandatory)" echo " -s, --subscription SUBSCRIPTION Subscription to which to make the deployment (mandatory)" + echo " -wk, --web-api-key WEB_API_KEY The API key for the backend web service" echo " -ai, --ai-service AI_SERVICE_TYPE Type of AI service to use (i.e., OpenAI or AzureOpenAI)" echo " -aikey, --ai-service-key AI_SERVICE_KEY API key for existing Azure OpenAI resource or OpenAI account" echo " -aiend, --ai-endpoint AI_ENDPOINT Endpoint for existing Azure OpenAI resource" @@ -20,6 +21,7 @@ usage() { echo " -nc, --no-cosmos-db Don't deploy Cosmos DB for chat storage - Use volatile memory instead" echo " -ns, --no-speech-services Don't deploy Speech Services to enable speech as chat input" echo " -dd, --debug-deployment Switches on verbose template deployment output" + echo " -ndp, --no-deploy-package Skips deploying the Web API package when set." } # Parse arguments @@ -36,6 +38,11 @@ while [[ $# -gt 0 ]]; do shift shift ;; + -wk|--web-api-key) + WEB_API_KEY="$2" + shift + shift + ;; -ai|--ai-service) AI_SERVICE_TYPE="$2" shift @@ -82,6 +89,10 @@ while [[ $# -gt 0 ]]; do DEBUG_DEPLOYMENT=true shift ;; + -ndp|--no-deploy-package) + NO_DEPLOY_PACKAGE=true + shift + ;; *) echo "Unknown option $1" usage @@ -96,6 +107,11 @@ if [[ -z "$DEPLOYMENT_NAME" ]] || [[ -z "$SUBSCRIPTION" ]] || [[ -z "$AI_SERVICE exit 1 fi +# Check if WEB_API_KEY is provided or not +if [[ -z "$WEB_API_KEY" ]]; then + WEB_API_KEY=$(uuidgen -r) +fi + # Check if AI_SERVICE_TYPE is either OpenAI or AzureOpenAI if [[ "${AI_SERVICE_TYPE,,}" != "openai" ]] && [[ "${AI_SERVICE_TYPE,,}" != "azureopenai" ]]; then echo "--ai-service must be either OpenAI or AzureOpenAI" @@ -154,11 +170,12 @@ az account set -s "$SUBSCRIPTION" # Create JSON config JSON_CONFIG=$(cat << EOF { - "name": { "value": "$DEPLOYMENT_NAME" }, + "webApiKey": { "value" : "$WEB_API_KEY" }, "webAppServiceSku": { "value": "$WEB_APP_SVC_SKU" }, "aiService": { "value": "$AI_SERVICE_TYPE" }, "aiApiKey": { "value": "$AI_SERVICE_KEY" }, - "aiEndpoint": { "value": "$([ -z "$AI_ENDPOINT" ] && echo "$AI_ENDPOINT")" }, + "deployWebApiPackage": { "value": $([ "$NO_DEPLOY_PACKAGE" = true ] && echo "false" || echo "true") }, + "aiEndpoint": { "value": "$([ ! -z "$AI_ENDPOINT" ] && echo "$AI_ENDPOINT")" }, "deployNewAzureOpenAI": { "value": $([ "$NO_NEW_AZURE_OPENAI" = true ] && echo "false" || echo "true") }, "deployQdrant": { "value": $([ "$NO_QDRANT" = true ] && echo "false" || echo "true") }, "deployCosmosDB": { "value": $([ "$NO_COSMOS_DB" = true ] && echo "false" || echo "true") }, diff --git a/deploy/deploy-webapi.sh b/deploy/deploy-webapi.sh old mode 100644 new mode 100755 index 6e0ea511e..fbc51a814 --- a/deploy/deploy-webapi.sh +++ b/deploy/deploy-webapi.sh @@ -70,14 +70,14 @@ fi az account set -s "$SUBSCRIPTION" echo "Getting Azure WebApp resource name..." -eval WEB_APP_NAME=$(az deployment group show --name $DEPLOYMENT_NAME --resource-group $RESOURCE_GROUP --output json | jq '.properties.outputs.webapiName.value') +eval WEB_APP_NAME=$(az deployment group show --name $DEPLOYMENT_NAME --resource-group $RESOURCE_GROUP --output json | jq -r '.properties.outputs.webapiName.value') # Ensure $WEB_APP_NAME is set if [[ -z "$WEB_APP_NAME" ]]; then echo "Could not get Azure WebApp resource name from deployment output." exit 1 fi -echo "Azure WebApp name: $webappName" +echo "Azure WebApp name: $WEB_APP_NAME" echo "Configuring Azure WebApp to run from package..." az webapp config appsettings set --resource-group $RESOURCE_GROUP --name $WEB_APP_NAME --settings WEBSITE_RUN_FROM_PACKAGE="1" @@ -86,12 +86,12 @@ if [ $? -ne 0 ]; then exit 1 fi -echo "Deploying '$PackageFilePath' to Azure WebApp '$webappName'..." -az webapp deployment source config-zip --resource-group $RESOURCE_GROUP --name $WEB_APP_NAME --src $PACKAGE_FILE_PATH +echo "Deploying '$PACKAGE_FILE_PATH' to Azure WebApp '$WEB_APP_NAME'..." +az webapp deployment source config-zip --resource-group $RESOURCE_GROUP --name $WEB_APP_NAME --src $PACKAGE_FILE_PATH --debug if [ $? -ne 0 ]; then - echo "Could not deploy '$PackageFilePath' to Azure WebApp '$webappName'." + echo "Could not deploy '$PACKAGE_FILE_PATH' to Azure WebApp '$WEB_APP_NAME'." exit 1 fi -eval WEB_APP_URL=$(az deployment group show --name $DEPLOYMENT_NAME --resource-group $RESOURCE_GROUP --output json | jq '.properties.outputs.webapiUrl.value') +eval WEB_APP_URL=$(az deployment group show --name $DEPLOYMENT_NAME --resource-group $RESOURCE_GROUP --output json | jq -r '.properties.outputs.webapiUrl.value') echo "To verify your deployment, go to 'https://$WEB_APP_URL/healthz' in your browser." diff --git a/deploy/deploy-webapp.ps1 b/deploy/deploy-webapp.ps1 index e9997946b..14fc44f0a 100644 --- a/deploy/deploy-webapp.ps1 +++ b/deploy/deploy-webapp.ps1 @@ -22,7 +22,12 @@ param( [Parameter(Mandatory)] [string] # Client application id - $ApplicationClientId + $ApplicationClientId, + + [Parameter(Mandatory=$false)] + [string] + # Authority for client applications that are not configured as multi-tenant. + $Authority="https://login.microsoftonline.com/common" ) Write-Host "Setting up Azure credentials..." @@ -56,7 +61,7 @@ $PSDefaultParameterValues['Out-File:Encoding'] = 'ascii' $envFilePath = "$PSScriptRoot/../webapp/.env" Write-Host "Writing environment variables to '$envFilePath'..." "REACT_APP_BACKEND_URI=https://$webapiUrl/" | Out-File -FilePath $envFilePath -"REACT_APP_AAD_AUTHORITY=https://login.microsoftonline.com/common" | Out-File -FilePath $envFilePath -Append +"REACT_APP_AAD_AUTHORITY=$Authority" | Out-File -FilePath $envFilePath -Append "REACT_APP_AAD_CLIENT_ID=$ApplicationClientId" | Out-File -FilePath $envFilePath -Append "REACT_APP_SK_API_KEY=$webapiApiKey" | Out-File -FilePath $envFilePath -Append diff --git a/deploy/deploy-webapp.sh b/deploy/deploy-webapp.sh old mode 100644 new mode 100755 index 13b49c6e4..69c7ea6bb --- a/deploy/deploy-webapp.sh +++ b/deploy/deploy-webapp.sh @@ -11,9 +11,11 @@ usage() { echo "" echo "Arguments:" echo " -s, --subscription SUBSCRIPTION Subscription to which to make the deployment (mandatory)" - echo " -rg, --resource-group RESOURCE_GROUP Resource group name from a 'deploy-azure.sh' deployment (mandatory)" + echo " -rg, --resource-group RESOURCE_GROUP Resource group name from a 'deploy-azure.sh' deployment (mandatory)" echo " -d, --deployment-name DEPLOYMENT_NAME Name of the deployment from a 'deploy-azure.sh' deployment (mandatory)" - echo " -a, --application-id Client application ID (mandatory)" + echo " -a, --application-id APPLICATION_ID Client application ID (mandatory)" + echo " -au, --authority Authority to use for client applications that are not configured as multi-tenant. Defaults to (https://login.microsoftonline.com/common) if not specified." + echo " -nr, --no-redirect Do not attempt to register redirect URIs with the client application" } # Parse arguments @@ -40,6 +42,15 @@ while [[ $# -gt 0 ]]; do shift shift ;; + -au|--authority) + AUTHORITY="$2" + shift + shift + ;; + -nr|--no-redirect) + NO_REDIRECT=true + shift + ;; *) echo "Unknown option $1" usage @@ -60,6 +71,10 @@ if [ $? -ne 0 ]; then az login --use-device-code fi +if [[-z "$AUTHORITY" ]]; then + AUTHORITY="https://login.microsoftonline.com/common" +fi + az account set -s "$SUBSCRIPTION" echo "Getting deployment outputs..." @@ -79,14 +94,19 @@ eval WEB_API_KEY=$(az webapp config appsettings list --name $WEB_API_NAME --reso ENV_FILE_PATH="$SCRIPT_ROOT/../webapp/.env" echo "Writing environment variables to '$ENV_FILE_PATH'..." echo "REACT_APP_BACKEND_URI=https://$WEB_API_URL/" > $ENV_FILE_PATH -echo "REACT_APP_AAD_AUTHORITY=https://login.microsoftonline.com/common" >> $ENV_FILE_PATH +echo "REACT_APP_AAD_AUTHORITY=$AUTHORITY" >> $ENV_FILE_PATH echo "REACT_APP_AAD_CLIENT_ID=$APPLICATION_ID" >> $ENV_FILE_PATH echo "REACT_APP_SK_API_KEY=$WEB_API_KEY" >> $ENV_FILE_PATH echo "Writing swa-cli.config.json..." SWA_CONFIG_FILE_PATH="$SCRIPT_ROOT/../webapp/swa-cli.config.json" -sed "s/{{appDevserverUrl}}/https:\/\/${WEB_APP_URL}/g" $SCRIPT_ROOT/../webapp/template.swa-cli.config.json > $SWA_CONFIG_FILE_PATH -cat $SWA_CONFIG_FILE_PATH +SWA_CONFIG_TEMPLATE_FILE_PATH="$SCRIPT_ROOT/../webapp/template.swa-cli.config.json" +swaConfig=`cat $SWA_CONFIG_TEMPLATE_FILE_PATH` +swaConfig=$(echo $swaConfig | sed "s/{{appDevserverUrl}}/https:\/\/${WEB_APP_URL}/") +swaConfig=$(echo $swaConfig | sed "s/{{appName}}/$WEB_API_NAME/") +swaConfig=$(echo $swaConfig | sed "s/{{resourceGroup}}/$RESOURCE_GROUP/") +swaConfig=$(echo $swaConfig | sed "s/{{subscription-id}}/$SUBSCRIPTION/") +echo $swaConfig > $SWA_CONFIG_FILE_PATH pushd "$SCRIPT_ROOT/../webapp" @@ -122,21 +142,23 @@ fi echo "Ensuring '$ORIGIN' is included in AAD app registration's redirect URIs..." eval OBJECT_ID=$(az ad app show --id $APPLICATION_ID | jq -r '.id') -REDIRECT_URIS=$(az rest --method GET --uri "https://graph.microsoft.com/v1.0/applications/$OBJECT_ID" --headers 'Content-Type=application/json' | jq -r '.spa.redirectUris') -if [[ ! "$REDIRECT_URIS" =~ "$ORIGIN" ]]; then - BODY="{spa:{redirectUris:['" - eval BODY+=$(echo $REDIRECT_URIS | jq $'join("\',\'")') - BODY+="','$ORIGIN']}}" - - az rest \ - --method PATCH \ - --uri "https://graph.microsoft.com/v1.0/applications/$OBJECT_ID" \ - --headers 'Content-Type=application/json' \ - --body $BODY -fi -if [ $? -ne 0 ]; then - echo "Failed to update app registration" - exit 1 +if [ "$NO_REDIRECT" != true ]; then + REDIRECT_URIS=$(az rest --method GET --uri "https://graph.microsoft.com/v1.0/applications/$OBJECT_ID" --headers 'Content-Type=application/json' | jq -r '.spa.redirectUris') + if [[ ! "$REDIRECT_URIS" =~ "$ORIGIN" ]]; then + BODY="{spa:{redirectUris:['" + eval BODY+=$(echo $REDIRECT_URIS | jq $'join("\',\'")') + BODY+="','$ORIGIN']}}" + + az rest \ + --method PATCH \ + --uri "https://graph.microsoft.com/v1.0/applications/$OBJECT_ID" \ + --headers 'Content-Type=application/json' \ + --body $BODY + fi + if [ $? -ne 0 ]; then + echo "Failed to update app registration" + exit 1 + fi fi popd diff --git a/deploy/main.bicep b/deploy/main.bicep index f60caeaff..7a3261fa3 100644 --- a/deploy/main.bicep +++ b/deploy/main.bicep @@ -9,7 +9,7 @@ Bicep template for deploying CopilotChat Azure resources. param name string = 'copichat' @description('SKU for the Azure App Service plan') -@allowed(['B1', 'S1', 'S2', 'S3', 'P1V3', 'P2V3', 'I1V2', 'I2V2' ]) +@allowed([ 'B1', 'S1', 'S2', 'S3', 'P1V3', 'P2V3', 'I1V2', 'I2V2' ]) param webAppServiceSku string = 'B1' @description('Location of package to deploy as the web service') @@ -55,6 +55,9 @@ param deployQdrant bool = true @description('Whether to deploy Azure Speech Services to enable input by voice') param deploySpeechServices bool = true +@description('Whether to deploy the backend Web API package') +param deployWebApiPackage bool = true + @description('Region for the resources') param location string = resourceGroup().location @@ -70,8 +73,7 @@ var uniqueName = '${name}-${rgIdHash}' @description('Name of the Azure Storage file share to create') var storageFileShareName = 'aciqdrantshare' - -resource openAI 'Microsoft.CognitiveServices/accounts@2022-12-01' = if(deployNewAzureOpenAI) { +resource openAI 'Microsoft.CognitiveServices/accounts@2022-12-01' = if (deployNewAzureOpenAI) { name: 'ai-${uniqueName}' location: location kind: 'OpenAI' @@ -83,7 +85,7 @@ resource openAI 'Microsoft.CognitiveServices/accounts@2022-12-01' = if(deployNew } } -resource openAI_completionModel 'Microsoft.CognitiveServices/accounts/deployments@2022-12-01' = if(deployNewAzureOpenAI) { +resource openAI_completionModel 'Microsoft.CognitiveServices/accounts/deployments@2022-12-01' = if (deployNewAzureOpenAI) { parent: openAI name: completionModel properties: { @@ -97,7 +99,7 @@ resource openAI_completionModel 'Microsoft.CognitiveServices/accounts/deployment } } -resource openAI_embeddingModel 'Microsoft.CognitiveServices/accounts/deployments@2022-12-01' = if(deployNewAzureOpenAI) { +resource openAI_embeddingModel 'Microsoft.CognitiveServices/accounts/deployments@2022-12-01' = if (deployNewAzureOpenAI) { parent: openAI name: embeddingModel properties: { @@ -109,7 +111,7 @@ resource openAI_embeddingModel 'Microsoft.CognitiveServices/accounts/deployments scaleType: 'Standard' } } - dependsOn: [ // This "dependency" is to create models sequentially because the resource + dependsOn: [// This "dependency" is to create models sequentially because the resource openAI_completionModel // provider does not support parallel creation of models properly. ] } @@ -283,7 +285,7 @@ resource appServiceWebConfig 'Microsoft.Web/sites/config@2022-09-01' = { } } -resource appServiceWebDeploy 'Microsoft.Web/sites/extensions@2022-09-01' = { +resource appServiceWebDeploy 'Microsoft.Web/sites/extensions@2022-09-01' = if (deployWebApiPackage) { name: 'MSDeploy' kind: 'string' parent: appServiceWeb @@ -311,9 +313,7 @@ resource appInsights 'Microsoft.Insights/components@2020-02-02' = { resource appInsightExtension 'Microsoft.Web/sites/siteextensions@2022-09-01' = { parent: appServiceWeb name: 'Microsoft.ApplicationInsights.AzureWebSites' - dependsOn: [ - appServiceWebDeploy - ] + dependsOn: [ appServiceWebConfig ] } resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10-01' = { @@ -531,9 +531,9 @@ resource cosmosAccount 'Microsoft.DocumentDB/databaseAccounts@2023-04-15' = if ( properties: { consistencyPolicy: { defaultConsistencyLevel: 'Session' } locations: [ { - locationName: location - failoverPriority: 0 - isZoneRedundant: false + locationName: location + failoverPriority: 0 + isZoneRedundant: false } ] databaseAccountOfferType: 'Standard' diff --git a/deploy/main.json b/deploy/main.json index 1f7539631..9ab7c188e 100644 --- a/deploy/main.json +++ b/deploy/main.json @@ -4,8 +4,8 @@ "metadata": { "_generator": { "name": "bicep", - "version": "0.16.2.56959", - "templateHash": "18037485528098010448" + "version": "0.19.5.34762", + "templateHash": "5601121958092657135" } }, "parameters": { @@ -121,6 +121,13 @@ "description": "Whether to deploy Azure Speech Services to enable input by voice" } }, + "deployWebApiPackage": { + "type": "bool", + "defaultValue": true, + "metadata": { + "description": "Whether to deploy the backend Web API package" + } + }, "location": { "type": "string", "defaultValue": "[resourceGroup().location]", @@ -392,6 +399,7 @@ ] }, { + "condition": "[parameters('deployWebApiPackage')]", "type": "Microsoft.Web/sites/extensions", "apiVersion": "2022-09-01", "name": "[format('{0}/{1}', format('app-{0}-webapi', variables('uniqueName')), 'MSDeploy')]", @@ -427,7 +435,7 @@ "name": "[format('{0}/{1}', format('app-{0}-webapi', variables('uniqueName')), 'Microsoft.ApplicationInsights.AzureWebSites')]", "dependsOn": [ "[resourceId('Microsoft.Web/sites', format('app-{0}-webapi', variables('uniqueName')))]", - "[resourceId('Microsoft.Web/sites/extensions', format('app-{0}-webapi', variables('uniqueName')), 'MSDeploy')]" + "[resourceId('Microsoft.Web/sites/config', format('app-{0}-webapi', variables('uniqueName')), 'web')]" ] }, { diff --git a/deploy/package-webapi.sh b/deploy/package-webapi.sh index 8f5da09eb..c36040f84 100644 --- a/deploy/package-webapi.sh +++ b/deploy/package-webapi.sh @@ -57,7 +57,7 @@ done # Set defaults : "${CONFIGURATION:="Release"}" : "${DOTNET:="net6.0"}" -: "${RUNTIME:="win-x64"}" +: "${RUNTIME:="linux-x64"}" : "${OUTPUT_DIRECTORY:="$SCRIPT_ROOT"}" PUBLISH_OUTPUT_DIRECTORY="$OUTPUT_DIRECTORY/publish" diff --git a/webapp/src/components/views/BackendProbe.tsx b/webapp/src/components/views/BackendProbe.tsx index e78048c6d..1a27f2018 100644 --- a/webapp/src/components/views/BackendProbe.tsx +++ b/webapp/src/components/views/BackendProbe.tsx @@ -34,7 +34,7 @@ const BackendProbe: FC = ({ uri, onBackendFound }) => { This sample expects to find a Semantic Kernel service from{' '} - samples/apps/copilot-chat-app/webapi running at {uri} + webapi/ running at {uri} Run your Semantic Kernel service locally using Visual Studio, Visual Studio Code or by typing the From a8d038deaa72b9af9de471725d5fd80a9e9e3b94 Mon Sep 17 00:00:00 2001 From: Desmond Howard Date: Fri, 21 Jul 2023 17:09:30 -0700 Subject: [PATCH 008/582] Show live updates from ChatSkill (#14) Original PR: https://github.com/microsoft/semantic-kernel/pull/2103. ------------------- ### Motivation and Context showing the current status of execution helps dampen the effect of the response latency. ### Description - updates `ChatSkill` to use the `MessageRelayHub` for broadcasting status updates - changes `botIsTyping` to `botResponseStatus` in `ChatState` ![gif](https://github.com/microsoft/semantic-kernel/assets/52973358/7e3720d8-2469-4fc5-a976-18d5c544e89f) ### Contribution Checklist - [x] The code builds clean without any errors or warnings - [X] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations - [X] All unit tests pass, and I have added new tests where possible - [X] I didn't break anyone :smile: --- .../CopilotChat/Controllers/ChatController.cs | 11 ++----- .../Extensions/SemanticKernelExtensions.cs | 3 ++ .../Skills/ChatSkills/ChatSkill.cs | 31 +++++++++++++++++++ webapp/src/components/chat/ChatInput.tsx | 6 +++- webapp/src/components/chat/ChatStatus.tsx | 9 +++--- .../TypingIndicatorRenderer.tsx | 31 ++++++++++--------- webapp/src/libs/useChat.ts | 8 ++--- .../redux/features/conversations/ChatState.ts | 2 +- .../conversations/conversationsSlice.ts | 11 ++++--- .../message-relay/signalRMiddleware.ts | 6 ++-- 10 files changed, 76 insertions(+), 42 deletions(-) diff --git a/webapi/CopilotChat/Controllers/ChatController.cs b/webapi/CopilotChat/Controllers/ChatController.cs index ae4d795f2..b79a907b7 100644 --- a/webapi/CopilotChat/Controllers/ChatController.cs +++ b/webapi/CopilotChat/Controllers/ChatController.cs @@ -42,7 +42,7 @@ public class ChatController : ControllerBase, IDisposable private const string ChatSkillName = "ChatSkill"; private const string ChatFunctionName = "Chat"; private const string ReceiveResponseClientCall = "ReceiveResponse"; - private const string GeneratingResponseClientCall = "ReceiveBotTypingState"; + private const string GeneratingResponseClientCall = "ReceiveBotResponseStatus"; public ChatController(ILogger logger, ITelemetryService telemetryService) { @@ -98,13 +98,6 @@ public async Task ChatAsync( return this.NotFound($"Failed to find {ChatSkillName}/{ChatFunctionName} on server"); } - // Broadcast bot typing state to all users - if (ask.Variables.Where(v => v.Key == "chatId").Any()) - { - var chatId = ask.Variables.Where(v => v.Key == "chatId").First().Value; - await messageRelayHubContext.Clients.Group(chatId).SendAsync(GeneratingResponseClientCall, chatId, true); - } - // Run the function. SKContext? result = null; try @@ -138,7 +131,7 @@ public async Task ChatAsync( { var chatId = ask.Variables.Where(v => v.Key == "chatId").First().Value; await messageRelayHubContext.Clients.Group(chatId).SendAsync(ReceiveResponseClientCall, chatSkillAskResult, chatId); - await messageRelayHubContext.Clients.Group(chatId).SendAsync(GeneratingResponseClientCall, chatId, false); + await messageRelayHubContext.Clients.Group(chatId).SendAsync(GeneratingResponseClientCall, chatId, null); } return this.Ok(chatSkillAskResult); diff --git a/webapi/CopilotChat/Extensions/SemanticKernelExtensions.cs b/webapi/CopilotChat/Extensions/SemanticKernelExtensions.cs index ac9a47a9c..e3b4ade0a 100644 --- a/webapi/CopilotChat/Extensions/SemanticKernelExtensions.cs +++ b/webapi/CopilotChat/Extensions/SemanticKernelExtensions.cs @@ -1,10 +1,12 @@ // Copyright (c) Microsoft. All rights reserved. using System; +using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.SemanticKernel; +using SemanticKernel.Service.CopilotChat.Hubs; using SemanticKernel.Service.CopilotChat.Options; using SemanticKernel.Service.CopilotChat.Skills.ChatSkills; using SemanticKernel.Service.CopilotChat.Storage; @@ -49,6 +51,7 @@ public static IKernel RegisterCopilotChatSkills(this IKernel kernel, IServicePro kernel: kernel, chatMessageRepository: sp.GetRequiredService(), chatSessionRepository: sp.GetRequiredService(), + messageRelayHubContext: sp.GetRequiredService>(), promptOptions: sp.GetRequiredService>(), documentImportOptions: sp.GetRequiredService>(), planner: sp.GetRequiredService(), diff --git a/webapi/CopilotChat/Skills/ChatSkills/ChatSkill.cs b/webapi/CopilotChat/Skills/ChatSkills/ChatSkill.cs index 2cf2fd0c1..c414b6690 100644 --- a/webapi/CopilotChat/Skills/ChatSkills/ChatSkill.cs +++ b/webapi/CopilotChat/Skills/ChatSkills/ChatSkill.cs @@ -8,6 +8,7 @@ using System.Text.Json; using System.Text.RegularExpressions; using System.Threading.Tasks; +using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.SemanticKernel; @@ -15,6 +16,7 @@ using Microsoft.SemanticKernel.Orchestration; using Microsoft.SemanticKernel.SkillDefinition; using Microsoft.SemanticKernel.TemplateEngine; +using SemanticKernel.Service.CopilotChat.Hubs; using SemanticKernel.Service.CopilotChat.Models; using SemanticKernel.Service.CopilotChat.Options; using SemanticKernel.Service.CopilotChat.Storage; @@ -43,6 +45,11 @@ public class ChatSkill /// private readonly ChatSessionRepository _chatSessionRepository; + /// + /// A SignalR hub context to broadcast updates of the execution. + /// + private readonly IHubContext _messageRelayHubContext; + /// /// Settings containing prompt texts. /// @@ -70,6 +77,7 @@ public ChatSkill( IKernel kernel, ChatMessageRepository chatMessageRepository, ChatSessionRepository chatSessionRepository, + IHubContext messageRelayHubContext, IOptions promptOptions, IOptions documentImportOptions, CopilotChatPlanner planner, @@ -79,6 +87,7 @@ public ChatSkill( this._chatMessageRepository = chatMessageRepository; this._chatSessionRepository = chatSessionRepository; this._promptOptions = promptOptions.Value; + this._messageRelayHubContext = messageRelayHubContext; this._semanticChatMemorySkill = new SemanticChatMemorySkill( promptOptions); @@ -249,6 +258,7 @@ public async Task ChatAsync( SKContext context) { // Save this new message to memory such that subsequent chat responses can use it + await this.UpdateResponseStatusOnClient(chatId, "Saving user message to chat history"); await this.SaveNewMessageAsync(message, userId, userName, chatId, messageType); // Clone the context to avoid modifying the original context variables. @@ -281,11 +291,13 @@ public async Task ChatAsync( context.Variables.Set("prompt", prompt); // Save this response to memory such that subsequent chat responses can use it + await this.UpdateResponseStatusOnClient(chatId, "Saving bot message to chat history"); ChatMessage botMessage = await this.SaveNewResponseAsync(response, prompt, chatId); context.Variables.Set("messageId", botMessage.Id); context.Variables.Set("messageType", ((int)botMessage.Type).ToString(CultureInfo.InvariantCulture)); // Extract semantic chat memory + await this.UpdateResponseStatusOnClient(chatId, "Extracting semantic chat memory"); await SemanticChatMemoryExtractor.ExtractSemanticChatMemoryAsync( chatId, this._kernel, @@ -306,6 +318,7 @@ await SemanticChatMemoryExtractor.ExtractSemanticChatMemoryAsync( private async Task GetChatResponseAsync(string chatId, SKContext chatContext) { // 0. Get the audience + await this.UpdateResponseStatusOnClient(chatId, "Extracting audience"); var audience = await this.GetAudienceAsync(chatContext); if (chatContext.ErrorOccurred) { @@ -313,6 +326,7 @@ private async Task GetChatResponseAsync(string chatId, SKContext chatCon } // 1. Extract user intent from the conversation history. + await this.UpdateResponseStatusOnClient(chatId, "Extracting user intent"); var userIntent = await this.GetUserIntentAsync(chatContext); if (chatContext.ErrorOccurred) { @@ -320,9 +334,11 @@ private async Task GetChatResponseAsync(string chatId, SKContext chatCon } // 2. Calculate the remaining token budget. + await this.UpdateResponseStatusOnClient(chatId, "Calculating remaining token budget"); var remainingToken = this.GetChatContextTokenLimit(userIntent); // 3. Acquire external information from planner + await this.UpdateResponseStatusOnClient(chatId, "Acquiring external information from planner"); var externalInformationTokenLimit = (int)(remainingToken * this._promptOptions.ExternalInformationContextWeight); var planResult = await this.AcquireExternalInformationAsync(chatContext, userIntent, externalInformationTokenLimit); if (chatContext.ErrorOccurred) @@ -333,10 +349,12 @@ private async Task GetChatResponseAsync(string chatId, SKContext chatCon // If plan is suggested, send back to user for approval before running if (this._externalInformationSkill.ProposedPlan != null) { + chatContext.Variables.Set("prompt", this._externalInformationSkill.ProposedPlan.Plan.Description); return JsonSerializer.Serialize(this._externalInformationSkill.ProposedPlan); } // 4. Query relevant semantic memories + await this.UpdateResponseStatusOnClient(chatId, "Querying semantic memories"); var chatMemoriesTokenLimit = (int)(remainingToken * this._promptOptions.MemoriesResponseContextWeight); var chatMemories = await this._semanticChatMemorySkill.QueryMemoriesAsync(userIntent, chatId, chatMemoriesTokenLimit, chatContext.Memory); if (chatContext.ErrorOccurred) @@ -345,6 +363,7 @@ private async Task GetChatResponseAsync(string chatId, SKContext chatCon } // 5. Query relevant document memories + await this.UpdateResponseStatusOnClient(chatId, "Querying document memories"); var documentContextTokenLimit = (int)(remainingToken * this._promptOptions.DocumentContextWeight); var documentMemories = await this._documentMemorySkill.QueryDocumentsAsync(userIntent, chatId, documentContextTokenLimit, chatContext.Memory); if (chatContext.ErrorOccurred) @@ -358,6 +377,7 @@ private async Task GetChatResponseAsync(string chatId, SKContext chatCon var chatContextTextTokenCount = remainingToken - Utilities.TokenCount(chatContextText); if (chatContextTextTokenCount > 0) { + await this.UpdateResponseStatusOnClient(chatId, "Extracting chat history"); var chatHistory = await this.ExtractChatHistoryAsync(chatId, chatContextTextTokenCount); if (chatContext.ErrorOccurred) { @@ -381,6 +401,7 @@ private async Task GetChatResponseAsync(string chatId, SKContext chatCon skillName: nameof(ChatSkill), description: "Complete the prompt."); + await this.UpdateResponseStatusOnClient(chatId, "Invoking the AI model"); chatContext = await completionFunction.InvokeAsync( context: chatContext, settings: this.CreateChatResponseCompletionSettings() @@ -628,5 +649,15 @@ private int GetChatContextTokenLimit(string userIntent) return remainingToken; } + /// + /// Update the status of the response on the client. + /// + /// Id of the chat session + /// Current status of the response + private async Task UpdateResponseStatusOnClient(string chatId, string status) + { + await this._messageRelayHubContext.Clients.Group(chatId).SendAsync("ReceiveBotResponseStatus", chatId, status); + } + # endregion } diff --git a/webapp/src/components/chat/ChatInput.tsx b/webapp/src/components/chat/ChatInput.tsx index 8c12fe304..e3d4566ae 100644 --- a/webapp/src/components/chat/ChatInput.tsx +++ b/webapp/src/components/chat/ChatInput.tsx @@ -14,7 +14,10 @@ import { GetResponseOptions, useChat } from '../../libs/useChat'; import { useAppDispatch, useAppSelector } from '../../redux/app/hooks'; import { RootState } from '../../redux/app/store'; import { addAlert } from '../../redux/features/app/appSlice'; -import { editConversationInput } from '../../redux/features/conversations/conversationsSlice'; +import { + editConversationInput, + updateBotResponseStatusFromServer, +} from '../../redux/features/conversations/conversationsSlice'; import { SpeechService } from './../../libs/services/SpeechService'; import { updateUserIsTyping } from './../../redux/features/conversations/conversationsSlice'; import { ChatStatus } from './ChatStatus'; @@ -150,6 +153,7 @@ export const ChatInput: React.FC = ({ isDraggingOver, onDragLeav setValue(''); dispatch(editConversationInput({ id: selectedId, newInput: '' })); + dispatch(updateBotResponseStatusFromServer({ chatId: selectedId, status: 'Calling the kernel' })); onSubmit({ value, messageType, chatId: selectedId }).catch((error) => { const message = `Error submitting chat input: ${(error as Error).message}`; log(message); diff --git a/webapp/src/components/chat/ChatStatus.tsx b/webapp/src/components/chat/ChatStatus.tsx index 8cd3971d8..fb17d3394 100644 --- a/webapp/src/components/chat/ChatStatus.tsx +++ b/webapp/src/components/chat/ChatStatus.tsx @@ -15,9 +15,7 @@ export const ChatStatus: React.FC = () => { React.useEffect(() => { const checkAreTyping = () => { const updatedTypingUsers: IChatUser[] = users.filter( - (chatUser: IChatUser) => - chatUser.id !== activeUserInfo?.id && - chatUser.isTyping, + (chatUser: IChatUser) => chatUser.id !== activeUserInfo?.id && chatUser.isTyping, ); setTypingUserList(updatedTypingUsers); @@ -26,6 +24,9 @@ export const ChatStatus: React.FC = () => { }, [activeUserInfo, users]); return ( - + ); }; diff --git a/webapp/src/components/chat/typing-indicator/TypingIndicatorRenderer.tsx b/webapp/src/components/chat/typing-indicator/TypingIndicatorRenderer.tsx index dce6952bf..36a193808 100644 --- a/webapp/src/components/chat/typing-indicator/TypingIndicatorRenderer.tsx +++ b/webapp/src/components/chat/typing-indicator/TypingIndicatorRenderer.tsx @@ -13,26 +13,23 @@ const useClasses = makeStyles({ }); interface TypingIndicatorRendererProps { - isBotTyping: boolean; + botResponseStatus: string | undefined; numberOfUsersTyping: number; } -export const TypingIndicatorRenderer: React.FC = ({ isBotTyping, numberOfUsersTyping }) => { +export const TypingIndicatorRenderer: React.FC = ({ + botResponseStatus, + numberOfUsersTyping, +}) => { const classes = useClasses(); - let message = ''; - if (isBotTyping) { - if (numberOfUsersTyping === 0) { - message = 'Bot is typing'; - } else if (numberOfUsersTyping === 1) { - message = 'Bot and 1 user are typing'; - } else { - message = `Bot and ${numberOfUsersTyping} users are typing`; - } - } else if (numberOfUsersTyping === 1) { - message = '1 user is typing'; + let message = botResponseStatus; + if (numberOfUsersTyping === 1) { + message = message ? `${message} and a user is typing` : 'A user is typing'; } else if (numberOfUsersTyping > 1) { - message = `${numberOfUsersTyping} users are typing`; + message = message + ? `${message} and ${numberOfUsersTyping} users are typing` + : `${numberOfUsersTyping} users are typing`; } if (!message) { @@ -46,5 +43,9 @@ export const TypingIndicatorRenderer: React.FC = ( ); - return {typingIndicator}; + return ( + + {typingIndicator} + + ); }; diff --git a/webapp/src/libs/useChat.ts b/webapp/src/libs/useChat.ts index 019f84d8d..951b027b5 100644 --- a/webapp/src/libs/useChat.ts +++ b/webapp/src/libs/useChat.ts @@ -82,7 +82,7 @@ export const useChat = () => { users: [loggedInUser], botProfilePicture: getBotProfilePicture(Object.keys(conversations).length), input: '', - isBotTyping: false, + botResponseStatus: undefined, userDataLoaded: false, }; @@ -153,7 +153,7 @@ export const useChat = () => { messages: chatMessages, botProfilePicture: getBotProfilePicture(Object.keys(loadedConversations).length), input: '', - isBotTyping: false, + botResponseStatus: undefined, userDataLoaded: false, }; } @@ -198,7 +198,7 @@ export const useChat = () => { users: [loggedInUser], messages: chatMessages, botProfilePicture: getBotProfilePicture(Object.keys(conversations).length), - isBotTyping: false, + botResponseStatus: undefined, }; dispatch(addConversation(newChat)); @@ -268,7 +268,7 @@ export const useChat = () => { users: chatUsers, botProfilePicture: getBotProfilePicture(Object.keys(conversations).length), input: '', - isBotTyping: false, + botResponseStatus: undefined, userDataLoaded: false, }; diff --git a/webapp/src/redux/features/conversations/ChatState.ts b/webapp/src/redux/features/conversations/ChatState.ts index d1a45fd9f..5eb09a720 100644 --- a/webapp/src/redux/features/conversations/ChatState.ts +++ b/webapp/src/redux/features/conversations/ChatState.ts @@ -11,6 +11,6 @@ export interface ChatState { botProfilePicture: string; lastUpdatedTimestamp?: number; input: string; - isBotTyping: boolean; + botResponseStatus: string | undefined; userDataLoaded: boolean; } diff --git a/webapp/src/redux/features/conversations/conversationsSlice.ts b/webapp/src/redux/features/conversations/conversationsSlice.ts index cad7bc2e9..1f929e3a9 100644 --- a/webapp/src/redux/features/conversations/conversationsSlice.ts +++ b/webapp/src/redux/features/conversations/conversationsSlice.ts @@ -10,7 +10,7 @@ import { Conversations, ConversationsState, ConversationTitleChange, - initialState + initialState, } from './ConversationsState'; export const conversationsSlice: Slice = createSlice({ @@ -104,13 +104,13 @@ export const conversationsSlice: Slice = createSlice({ const { userId, chatId, isTyping } = action.payload; updateUserTypingState(state, userId, chatId, isTyping); }, - updateBotIsTypingFromServer: ( + updateBotResponseStatusFromServer: ( state: ConversationsState, - action: PayloadAction<{ chatId: string; isTyping: boolean }>, + action: PayloadAction<{ chatId: string; status: string }>, ) => { - const { chatId, isTyping } = action.payload; + const { chatId, status } = action.payload; const conversation = state.conversations[chatId]; - conversation.isBotTyping = isTyping; + conversation.botResponseStatus = status; }, }, }); @@ -126,6 +126,7 @@ export const { updateMessageState, updateUserIsTyping, updateUserIsTypingFromServer, + updateBotResponseStatusFromServer, setUsersLoaded, } = conversationsSlice.actions; diff --git a/webapp/src/redux/features/message-relay/signalRMiddleware.ts b/webapp/src/redux/features/message-relay/signalRMiddleware.ts index 76579a789..7efedc189 100644 --- a/webapp/src/redux/features/message-relay/signalRMiddleware.ts +++ b/webapp/src/redux/features/message-relay/signalRMiddleware.ts @@ -17,7 +17,7 @@ const enum SignalRCallbackMethods { ReceiveResponse = 'ReceiveResponse', UserJoined = 'UserJoined', ReceiveUserTypingState = 'ReceiveUserTypingState', - ReceiveBotTypingState = 'ReceiveBotTypingState', + ReceiveBotResponseStatus = 'ReceiveBotResponseStatus', GlobalDocumentUploaded = 'GlobalDocumentUploaded', ChatDocumentUploaded = 'ChatDocumentUploaded', ChatEdited = 'ChatEdited', @@ -196,8 +196,8 @@ export const registerSignalREvents = (store: Store) => { }, ); - hubConnection.on(SignalRCallbackMethods.ReceiveBotTypingState, (chatId: string, isTyping: boolean) => { - store.dispatch({ type: 'conversations/updateBotIsTypingFromServer', payload: { chatId, isTyping } }); + hubConnection.on(SignalRCallbackMethods.ReceiveBotResponseStatus, (chatId: string, status: string) => { + store.dispatch({ type: 'conversations/updateBotResponseStatusFromServer', payload: { chatId, status } }); }); hubConnection.on(SignalRCallbackMethods.GlobalDocumentUploaded, (fileNames: string, userName: string) => { From c13010bcc26301fb681dcc87965aa4032905d7fd Mon Sep 17 00:00:00 2001 From: Gil LaHaye Date: Fri, 21 Jul 2023 18:17:54 -0600 Subject: [PATCH 009/582] Add support for Azure Cognitive Search's Vector Search (#12) ### Motivation and Context We want to have support for Microsoft's vector solution. ### Description Add support for Azure Cognitive Search's Vector Search ### Contribution Checklist - [ ] The code builds clean without any errors or warnings - [ ] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone :smile: --- webapi/CopilotChatWebApi.csproj | 13 ++++++------ webapi/Options/AzureCognitiveSearchOptions.cs | 6 ++++++ webapi/README.md | 12 +++++++++++ webapi/SemanticKernelExtensions.cs | 21 +++++++++++++++++-- webapi/ServiceExtensions.cs | 2 -- webapi/appsettings.json | 15 ++++++++----- 6 files changed, 54 insertions(+), 15 deletions(-) diff --git a/webapi/CopilotChatWebApi.csproj b/webapi/CopilotChatWebApi.csproj index 964e845d1..59e9f4aea 100644 --- a/webapi/CopilotChatWebApi.csproj +++ b/webapi/CopilotChatWebApi.csproj @@ -11,13 +11,14 @@ - - + + - - - - + + + + + diff --git a/webapi/Options/AzureCognitiveSearchOptions.cs b/webapi/Options/AzureCognitiveSearchOptions.cs index ee9707939..2a374b26b 100644 --- a/webapi/Options/AzureCognitiveSearchOptions.cs +++ b/webapi/Options/AzureCognitiveSearchOptions.cs @@ -20,4 +20,10 @@ public class AzureCognitiveSearchOptions /// [Required, NotEmptyOrWhitespace] public string Key { get; set; } = string.Empty; + + /// + /// Use ACS's vector search feature when set to true. (See https://learn.microsoft.com/en-us/azure/search/vector-search-overview) + /// Otherwise, use semantic search. (See https://learn.microsoft.com/en-us/azure/search/semantic-search-overview) + /// + public bool UseVectorSearch { get; set; } = false; } diff --git a/webapi/README.md b/webapi/README.md index 6bb3d63fc..e833ae3d9 100644 --- a/webapi/README.md +++ b/webapi/README.md @@ -114,6 +114,18 @@ Before you get started, make sure you have the following additional requirements ``` > To stop the container, in another terminal window run `docker container stop copilotchat; docker container rm copilotchat;`. +# (Optional) Enabling the Azure Cognitive Search Memory Store + +Azure Cognitive Search can be used as a persistent memory store for Copilot Chat. +The service can be used with either its [semantic search](https://learn.microsoft.com/en-us/azure/search/semantic-search-overview) +or its [vector search](https://learn.microsoft.com/en-us/azure/search/vector-search-overview). + +When using semantic search, the service will provide a high-level ingestion mechanism that abstracts away the details of how the data is ingested. +To use semantic search, make sure to enable the `Semantic Search` feature on your Azure Cognitive Search service. + +When using vector search, you have more control over the ingestion but must provide the embeddings to save into the database yourself. +Contrary to semantic search, vector search makes use of the embedding configuration you set in appsettings.json. + # (Optional) Enable Application Insights telemetry Enabling telemetry on CopilotChatApi allows you to capture data about requests to and from the API, allowing you to monitor the deployment and monitor how the application is being used. diff --git a/webapi/SemanticKernelExtensions.cs b/webapi/SemanticKernelExtensions.cs index 5432bccfd..54e0d1770 100644 --- a/webapi/SemanticKernelExtensions.cs +++ b/webapi/SemanticKernelExtensions.cs @@ -11,6 +11,7 @@ using Microsoft.SemanticKernel.AI.Embeddings; using Microsoft.SemanticKernel.Connectors.AI.OpenAI.TextEmbedding; using Microsoft.SemanticKernel.Connectors.Memory.AzureCognitiveSearch; +using Microsoft.SemanticKernel.Connectors.Memory.AzureSearch; using Microsoft.SemanticKernel.Connectors.Memory.Qdrant; using Microsoft.SemanticKernel.Memory; using Microsoft.SemanticKernel.Skills.Core; @@ -142,14 +143,30 @@ private static void AddSemanticTextMemory(this IServiceCollection services) throw new InvalidOperationException("MemoriesStore type is AzureCognitiveSearch and AzureCognitiveSearch configuration is null."); } - services.AddSingleton(sp => new AzureCognitiveSearchMemory(config.AzureCognitiveSearch.Endpoint, config.AzureCognitiveSearch.Key)); + // ACS's vector search where users provide their embeddings + if (config.AzureCognitiveSearch.UseVectorSearch) + { + services.AddSingleton(sp => + { + return new AzureSearchMemoryStore(config.AzureCognitiveSearch.Endpoint, config.AzureCognitiveSearch.Key); + }); + services.AddScoped(sp => new SemanticTextMemory( + sp.GetRequiredService(), + sp.GetRequiredService>().Value + .ToTextEmbeddingsService(logger: sp.GetRequiredService>()))); + } + // ACS's semantic search where ACS calculates the embeddings + else + { + services.AddSingleton(sp => new AzureCognitiveSearchMemory(config.AzureCognitiveSearch.Endpoint, config.AzureCognitiveSearch.Key)); + } break; default: throw new InvalidOperationException($"Invalid 'MemoriesStore' type '{config.Type}'."); } - // High level semantic memory implementations, such as Azure Cognitive Search, do not allow for providing embeddings when storing memories. + // High level semantic memory implementations, such as Azure Cognitive Search's Semantic Search, do not allow for providing embeddings when storing memories. // We wrap the memory store in an optional memory store to allow controllers to pass dependency injection validation and potentially optimize // for a lower-level memory implementation (e.g. Qdrant). Lower level memory implementations (i.e., IMemoryStore) allow for reusing embeddings, // whereas high level memory implementation (i.e., ISemanticTextMemory) assume embeddings get recalculated on every write. diff --git a/webapi/ServiceExtensions.cs b/webapi/ServiceExtensions.cs index 1b8768e01..06c0baaae 100644 --- a/webapi/ServiceExtensions.cs +++ b/webapi/ServiceExtensions.cs @@ -35,8 +35,6 @@ internal static IServiceCollection AddOptions(this IServiceCollection services, .ValidateOnStart() .PostConfigure(TrimStringProperties); - var foo = services.BuildServiceProvider().GetService>(); - // Authorization configuration services.AddOptions() .Bind(configuration.GetSection(AuthorizationOptions.PropertyName)) diff --git a/webapi/appsettings.json b/webapi/appsettings.json index c345f9c1f..d162bbd6d 100644 --- a/webapi/appsettings.json +++ b/webapi/appsettings.json @@ -103,11 +103,15 @@ } }, // - // Memories stores are used for storing new memories and retrieving semantically similar memories. + // Memory stores are used for storing new memories and retrieving semantically similar memories. // - Supported Types are "volatile", "qdrant", or "azurecognitivesearch". // - When using Qdrant or Azure Cognitive Search, see ./README.md for deployment instructions. - // - The "Semantic Search" feature must be enabled on Azure Cognitive Search. - // - The Embedding configuration above will not be used when Azure Cognitive Search is selected. + // - If Azure Cognitive Search is selected AND UseVectorSearch is set to false, you will be + // using ACS's semantic search (https://learn.microsoft.com/en-us/azure/search/semantic-search-overview) + // instead of its vector search feature (https://learn.microsoft.com/en-us/azure/search/vector-search-overview) + // This means that: + // * The "Semantic Search" feature must be enabled on Azure Cognitive Search. + // * The Embedding configuration above will not be used. // - Set "MemoriesStore:AzureCognitiveSearch:Key" using dotnet's user secrets (see above) // (i.e. dotnet user-secrets set "MemoriesStore:AzureCognitiveSearch:Key" "MY_AZCOGSRCH_KEY") // - Set "MemoriesStore:Qdrant:Key" using dotnet's user secrets (see above) if you are using a Qdrant Cloud instance. @@ -122,6 +126,7 @@ // "Key": "" }, "AzureCognitiveSearch": { + "UseVectorSearch": true, "Endpoint": "" // "Key": "" } @@ -150,8 +155,8 @@ // - Obtain language data files here: https://github.com/tesseract-ocr/tessdata . // - Add these files to your `data` folder or the path specified in the "FilePath" property and set the "Copy to Output Directory" value to "Copy if newer". // -"OcrSupport": { - "Type": "tesseract", + "OcrSupport": { + "Type": "none", "Tesseract": { "Language": "eng", "FilePath": "./data" From 75bbe3f49745259e7a5b4ae1f61e041e6cd5c20e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 08:22:35 -0700 Subject: [PATCH 010/582] Bump typescript from 5.0.4 to 5.1.6 in /webapp (#20) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [typescript](https://github.com/Microsoft/TypeScript) from 5.0.4 to 5.1.6.
Release notes

Sourced from typescript's releases.

TypeScript 5.1.6

For release notes, check out the release announcement.

For the complete list of fixed issues, check out the

Downloads are available on npm

TypeScript 5.1.5

For release notes, check out the release announcement.

For the complete list of fixed issues, check out the

Downloads are available on:

TypeScript 5.1.3

For release notes, check out the release announcement.

For the complete list of fixed issues, check out the

Downloads are available on:

TypeScript 5.1 RC

For release notes, check out the release announcement.

For the complete list of fixed issues, check out the

... (truncated)

Commits
  • 6e4aa90 Bump version to 5.1.6 and LKG
  • ac5884a cherry pick "No this type arguments in base constraints (#54536)" to releas...
  • e7f1caf Bump version to 5.1.5 and LKG
  • f244192 Pick 54781 to release 5.1 (#54792)
  • db3575a 🤖 Pick PR #54588 (Fixed a regression with string comp...) into release-5.1 (#...
  • 2faa176 🤖 Pick PR #54599 (fix(dts): JsxSpreadAttribute - re...) into release-5.1 (#...
  • 668c93b 🤖 Pick PR #54578 (Switch from corepack to a global np...) into release-5.1 (#...
  • 2d031ce 🤖 Pick PR #54656 (fix: no variable suggestions withou...) into release-5.1 (#...
  • e6ceba0 Bump version to 5.1.4 and LKG
  • d1259a1 🤖 Pick PR #54507 (Ensure we don't overwrite computed ...) into release-5.1 (#...
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=typescript&package-manager=npm_and_yarn&previous-version=5.0.4&new-version=5.1.6)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- webapp/package.json | 2 +- webapp/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 82b7148a3..e63f7d960 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -46,7 +46,7 @@ "http-server": "^14.1.1", "prettier": "^2.8.1", "serve": "^14.2.0", - "typescript": "5.0.4", + "typescript": "5.1.6", "vsts-npm-auth": "^0.42.1", "workbox-window": "^7.0.0" }, diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 445429ceb..2e9ed16a7 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -10879,10 +10879,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typescript@5.0.4: - version "5.0.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.0.4.tgz#b217fd20119bd61a94d4011274e0ab369058da3b" - integrity sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw== +typescript@5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" + integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== unbox-primitive@^1.0.2: version "1.0.2" From b063dc782e5dc9f8922ab848cf87fda849cb3df1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 08:23:38 -0700 Subject: [PATCH 011/582] Bump @fluentui/react-components from 9.26.1 to 9.26.2 in /webapp (#22) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [@fluentui/react-components](https://github.com/microsoft/fluentui) from 9.26.1 to 9.26.2.
Release notes

Sourced from @​fluentui/react-components's releases.

@​fluentui/react-components v9.26.2

Minor changes

  • chore: Exporting MENU_ENTER_EVENT and dispatchMenuEnterEvent utilities. (PR #28499 by khmakoto)

Patches

  • fix: high contrast mode hover style icon fixes (PR #28156 by emmayjiang)
  • fix: updated right border token in primary variant of split button (PR #28555 by kkakroo)
  • fix: add @​swc/helpers to deps instead of tslib as we use swc for transpilation (PR #28599 by Hotell)
  • bugfix: moves handleBackdropClick from defaultProps to an override (PR #28579 by bsunderhus)
  • fix: MenuItem content should be spaced 12px from the boundary (PR #28162 by ling1726)
  • fix(PortalCompatProvider): support custom ID prefixes in themeClassName (PR #28551 by alina-zaieva)
  • fix: Remove empty makeStyles call. (PR #28566 by benlemmon-ms)

Prerelease changes

Commits
  • bc5c683 applying package updates
  • 5a4b167 chore: migrate to monosize (#26826)
  • d803aee fix(react-conformance): add @​swc/helpers to deps instead of tslib as we use s...
  • 631543d fix: MenuItem content should be spaced 12px from the boundary (#28162)
  • f5b6134 feat: implements selection (#28497)
  • 21d69b7 bugfix: moves handleBackdropClick from defaultProps to an override (#28579)
  • 2adf9de Fix empty CSS creation (#28566)
  • ff9dc9f chore: replace plop with nx within create-* aliases in root package.json (#28...
  • 4838add applying package updates
  • 638b05a fix: High contrast mode hover style icon fixes in react-button components (#2...
  • Additional commits viewable in compare view

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@fluentui/react-components&package-manager=npm_and_yarn&previous-version=9.26.1&new-version=9.26.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- webapp/package.json | 2 +- webapp/yarn.lock | 592 ++++++++++++++++++++++---------------------- 2 files changed, 298 insertions(+), 296 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index e63f7d960..236115ca6 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -20,7 +20,7 @@ "@azure/ms-rest-js": "^2.6.4", "@azure/msal-browser": "^2.32.1", "@azure/msal-react": "^1.5.1", - "@fluentui/react-components": "^9.13.0", + "@fluentui/react-components": "^9.26.2", "@fluentui/react-icons": "^2.0.193", "@fluentui/react-northstar": "^0.66.4", "@microsoft/signalr": "^7.0.5", diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 2e9ed16a7..fd89b9467 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -1407,15 +1407,15 @@ dependencies: "@swc/helpers" "^0.4.14" -"@fluentui/react-accordion@^9.1.23": - version "9.1.23" - resolved "https://registry.yarnpkg.com/@fluentui/react-accordion/-/react-accordion-9.1.23.tgz#a3339ea748851ec67a24d96351686f45999decd7" - integrity sha512-Cast99R8Tq/Z+jyriZxd1hOeNkgfe1WZiOi5DLd3Ow0H1Os2HJDss/YgpU3ZHXHY/A/AcHWNzwv801Ub8mhBhA== +"@fluentui/react-accordion@^9.1.24": + version "9.1.24" + resolved "https://registry.yarnpkg.com/@fluentui/react-accordion/-/react-accordion-9.1.24.tgz#c7ab4dae6ac44e5f4055032ecc2d20a9bd59abb4" + integrity sha512-27kc3c1JJP5cNlVFKuri3nhFVI7iePwYcUHKQfVcuYZpKJhuuZUSUbp/j0dI4JOYhfTlifCBggq7Z1epbD/Ifw== dependencies: - "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-aria" "^9.3.27" "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -1423,55 +1423,55 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-alert@9.0.0-beta.58": - version "9.0.0-beta.58" - resolved "https://registry.yarnpkg.com/@fluentui/react-alert/-/react-alert-9.0.0-beta.58.tgz#0b32c918aa1bc1547f26c60680c01c19109560b8" - integrity sha512-i4JZIW0YAxaNslcI5YAx7KrjWxVYCOqVWI+kZ+pD2bsSYzuh2XNoddi/VVJAK/ckpafM3ZDVW7ZfTmZ9O/XaHg== +"@fluentui/react-alert@9.0.0-beta.59": + version "9.0.0-beta.59" + resolved "https://registry.yarnpkg.com/@fluentui/react-alert/-/react-alert-9.0.0-beta.59.tgz#d7315a6c1389e834798e8d6b9346600f43fc0283" + integrity sha512-Wcc1HYQoITMIEiDKbY6dK1zQt6PymXXGQs2wtnUCXvh60AuGW9P4E7lEqNJB6Uh+vVyW9HUyXTZ/HyxY+/xtGg== dependencies: - "@fluentui/react-avatar" "^9.5.12" - "@fluentui/react-button" "^9.3.23" + "@fluentui/react-avatar" "^9.5.13" + "@fluentui/react-button" "^9.3.24" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-aria@^9.3.26": - version "9.3.26" - resolved "https://registry.yarnpkg.com/@fluentui/react-aria/-/react-aria-9.3.26.tgz#03e0ea8f6fa80b5e07f171f010b4634369d0da5b" - integrity sha512-3COvfltw3yn0p93HBWf1XmOv5A/sJ1jfsxtNeoum0+RivMs+L9CgTS5/d86t8xiQrxw1JXtWBzDaBwHBasE6Aw== +"@fluentui/react-aria@^9.3.27": + version "9.3.27" + resolved "https://registry.yarnpkg.com/@fluentui/react-aria/-/react-aria-9.3.27.tgz#6feb33743168af4bf05e1f6488229bd7fdaf1c9d" + integrity sha512-cp+vB6E4X25DmE0RSmsnjAvmeHVAR3h+112z42ZuOF8/Rl7s7Pw8rGqMEGdIslJ29cx1Ka/raHTBn8h+OQB3Mw== dependencies: "@fluentui/keyboard-keys" "^9.0.3" "@fluentui/react-utilities" "^9.10.1" "@swc/helpers" "^0.4.14" -"@fluentui/react-avatar@^9.5.12": - version "9.5.12" - resolved "https://registry.yarnpkg.com/@fluentui/react-avatar/-/react-avatar-9.5.12.tgz#de63336de6696b605f5cfe6c4c95ff0465f9964e" - integrity sha512-Z5frthUPQQjJjzP5MZEXzzw5WymKvBfESAnW45+ZeJezgY/RBPxV8QgT+l39MeNeULjZgtTU7sH0m6NejQBt8g== +"@fluentui/react-avatar@^9.5.13": + version "9.5.13" + resolved "https://registry.yarnpkg.com/@fluentui/react-avatar/-/react-avatar-9.5.13.tgz#c975a7ccedf25e76a00c8394e5beb078a0d0d3c9" + integrity sha512-0Aekmz9BqfG4r5bsF48EKFHndv+b3NU1x1UpE+7PpRiU7AsTZ1Z2rLdmdxowL9lAZvJeRlAFntZMoo6jEwj6ag== dependencies: - "@fluentui/react-badge" "^9.1.20" + "@fluentui/react-badge" "^9.1.21" "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-popover" "^9.7.6" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-popover" "^9.7.7" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-tooltip" "^9.2.23" + "@fluentui/react-tooltip" "^9.2.24" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-badge@^9.1.20": - version "9.1.20" - resolved "https://registry.yarnpkg.com/@fluentui/react-badge/-/react-badge-9.1.20.tgz#c8ec521666de09248f833eb7470116410ace0b47" - integrity sha512-vfbooJgbVIUITsNUprS4C8/HYbhyZS2JhLXzHnrrxF9/VxgLMjVY49neCFyNmLRp4VCi92ECMz6ekFzL2cym+g== +"@fluentui/react-badge@^9.1.21": + version "9.1.21" + resolved "https://registry.yarnpkg.com/@fluentui/react-badge/-/react-badge-9.1.21.tgz#8edab4a7356cd7e6b008ad39b4139a7c208075f3" + integrity sha512-sYW9tQUDVvkfuwMmvLzNQsBKMBjuIzgEb3v7tgtG5sx7w4dJrTqsTGWvVsExamES2UZmtSVd0UneMiWSOhZ4Og== dependencies: "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" @@ -1497,15 +1497,15 @@ prop-types "^15.7.2" react-is "^17.0.2" -"@fluentui/react-button@^9.3.23": - version "9.3.23" - resolved "https://registry.yarnpkg.com/@fluentui/react-button/-/react-button-9.3.23.tgz#4647a6cb14634fd86803be335efc1df00e217a68" - integrity sha512-YzBmu8gV06j9TyioPHThSeybCkNlVnKJRXY/XKS+8mkJBOZA0ZsKv3UwlSQHyM1Ov4wku2JPCotW37lbUOOKLg== +"@fluentui/react-button@^9.3.24": + version "9.3.24" + resolved "https://registry.yarnpkg.com/@fluentui/react-button/-/react-button-9.3.24.tgz#ead9fea771de405b6ba0415150b286a3365d33b0" + integrity sha512-Ao2CETge8e9AI72tMcrGCOfyOvVYXKTAgt0DC9OLoAjRWyqckMf0nOit5GmKV9se9TjLXnLQC2DV0G/0iHrzJQ== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-aria" "^9.3.27" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -1513,28 +1513,28 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-card@^9.0.22": - version "9.0.22" - resolved "https://registry.yarnpkg.com/@fluentui/react-card/-/react-card-9.0.22.tgz#0388853d58d94fcc9db7d9539692cdb7a4227090" - integrity sha512-/ay8kMPKn7/utLAvaIbUuro2FMxkpJ+klzwm7I4AGOOrpLr5ajsYQ5LX6W3FrMsLgGZFKXFpM4sl7qOgsI28Cg== +"@fluentui/react-card@^9.0.23": + version "9.0.23" + resolved "https://registry.yarnpkg.com/@fluentui/react-card/-/react-card-9.0.23.tgz#c29a4847bf763b2110a733cf2a799c168ff0864f" + integrity sha512-zNHLnHzt2ddtBKQsi7q3ZpjvpIn8mxiFmiPQl2qsmJy8MZyK8NYyEcyshB7z3XeBMS2pHTXqdq5aiqMzgbrv5A== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-checkbox@^9.1.24": - version "9.1.24" - resolved "https://registry.yarnpkg.com/@fluentui/react-checkbox/-/react-checkbox-9.1.24.tgz#0e90386fcc00b37b86376356aec72ebf4117e6fb" - integrity sha512-S4eUBaTMgzL5eDVhSymL6R9dHc3aV61OTojrRjXyc0utUhziCtijj9uZ0jlQ4G5l5ZrQcfpDZQxuSDOGQ2Mcpg== +"@fluentui/react-checkbox@^9.1.25": + version "9.1.25" + resolved "https://registry.yarnpkg.com/@fluentui/react-checkbox/-/react-checkbox-9.1.25.tgz#eac70bab37467749f217b3093a85aa1eba28fbc2" + integrity sha512-MX14BuzxOFE5QQpq37xjcju3INdX/L+pHsfevgogqg8fi3hWjqMZRCxnDYkjhR7OIV0s4PY0xFWYZL6FvYLp2Q== dependencies: - "@fluentui/react-field" "^9.1.11" + "@fluentui/react-field" "^9.1.12" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-label" "^9.1.20" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-label" "^9.1.21" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -1542,17 +1542,17 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-combobox@^9.4.7": - version "9.4.7" - resolved "https://registry.yarnpkg.com/@fluentui/react-combobox/-/react-combobox-9.4.7.tgz#2bfc30ad4964446ec0242a8b89995f3e47d59716" - integrity sha512-dr9DvEtCl7v3/4TeAVQ2a7ynRYuxRTjRd5UFoZSg2p5/iot4F1Xk2Q8/mEj7T4/nZy5gaK5F3k6V54YjYrsdHQ== +"@fluentui/react-combobox@^9.4.8": + version "9.4.8" + resolved "https://registry.yarnpkg.com/@fluentui/react-combobox/-/react-combobox-9.4.8.tgz#2e45236c17fd50098176f548cc9fa7eeb13cd78e" + integrity sha512-L+WwsbKSeh9RwT1kM9oMBqTnLN+CdOFWstpAOd8M9GCKwiQeDMmFosxuFHgIiLOLJ5LYpIFJ+b8QHvmkDFotyg== dependencies: "@fluentui/keyboard-keys" "^9.0.3" "@fluentui/react-context-selector" "^9.1.26" - "@fluentui/react-field" "^9.1.11" + "@fluentui/react-field" "^9.1.12" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-portal" "^9.3.2" "@fluentui/react-positioning" "^9.8.0" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" @@ -1583,56 +1583,56 @@ "@babel/runtime" "^7.10.4" react-is "^17.0.2" -"@fluentui/react-components@^9.13.0": - version "9.26.1" - resolved "https://registry.yarnpkg.com/@fluentui/react-components/-/react-components-9.26.1.tgz#ddc907a9062e98ccd357ac8982a986177d7e9aa3" - integrity sha512-IeGamHc0D0IjkYxLBTqnDdZkLrKLh5x+8k++0sihkNxmVmjZUB0ZyYq7F0z6pv8XuyMjcJhvG/StuJcVOorqLQ== - dependencies: - "@fluentui/react-accordion" "^9.1.23" - "@fluentui/react-alert" "9.0.0-beta.58" - "@fluentui/react-avatar" "^9.5.12" - "@fluentui/react-badge" "^9.1.20" - "@fluentui/react-button" "^9.3.23" - "@fluentui/react-card" "^9.0.22" - "@fluentui/react-checkbox" "^9.1.24" - "@fluentui/react-combobox" "^9.4.7" - "@fluentui/react-dialog" "^9.5.16" - "@fluentui/react-divider" "^9.2.20" - "@fluentui/react-drawer" "9.0.0-beta.8" - "@fluentui/react-field" "^9.1.11" - "@fluentui/react-image" "^9.1.17" - "@fluentui/react-infobutton" "9.0.0-beta.42" - "@fluentui/react-input" "^9.4.21" - "@fluentui/react-label" "^9.1.20" - "@fluentui/react-link" "^9.1.2" - "@fluentui/react-menu" "^9.10.0" +"@fluentui/react-components@^9.26.2": + version "9.26.2" + resolved "https://registry.yarnpkg.com/@fluentui/react-components/-/react-components-9.26.2.tgz#935ea6bf9070d68b33f2d7da1dc92a29167925a3" + integrity sha512-EFePZGfpHJlaIqhg5JHmZn+R8wMUSs/KVwANAKx6dosucmzgU5e56nakYCIlWPGQYsLit8wqWgaUxvsjGgyDyQ== + dependencies: + "@fluentui/react-accordion" "^9.1.24" + "@fluentui/react-alert" "9.0.0-beta.59" + "@fluentui/react-avatar" "^9.5.13" + "@fluentui/react-badge" "^9.1.21" + "@fluentui/react-button" "^9.3.24" + "@fluentui/react-card" "^9.0.23" + "@fluentui/react-checkbox" "^9.1.25" + "@fluentui/react-combobox" "^9.4.8" + "@fluentui/react-dialog" "^9.5.17" + "@fluentui/react-divider" "^9.2.21" + "@fluentui/react-drawer" "9.0.0-beta.9" + "@fluentui/react-field" "^9.1.12" + "@fluentui/react-image" "^9.1.18" + "@fluentui/react-infobutton" "9.0.0-beta.43" + "@fluentui/react-input" "^9.4.22" + "@fluentui/react-label" "^9.1.21" + "@fluentui/react-link" "^9.1.3" + "@fluentui/react-menu" "^9.11.0" "@fluentui/react-overflow" "^9.0.23" - "@fluentui/react-persona" "^9.2.22" - "@fluentui/react-popover" "^9.7.6" - "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-persona" "^9.2.23" + "@fluentui/react-popover" "^9.7.7" + "@fluentui/react-portal" "^9.3.2" "@fluentui/react-positioning" "^9.8.0" - "@fluentui/react-progress" "^9.1.21" - "@fluentui/react-provider" "^9.7.9" - "@fluentui/react-radio" "^9.1.24" - "@fluentui/react-select" "^9.1.21" + "@fluentui/react-progress" "^9.1.22" + "@fluentui/react-provider" "^9.7.10" + "@fluentui/react-radio" "^9.1.25" + "@fluentui/react-select" "^9.1.22" "@fluentui/react-shared-contexts" "^9.6.0" - "@fluentui/react-skeleton" "^9.0.9" - "@fluentui/react-slider" "^9.1.24" - "@fluentui/react-spinbutton" "^9.2.21" - "@fluentui/react-spinner" "^9.3.0" - "@fluentui/react-switch" "^9.1.24" - "@fluentui/react-table" "^9.6.0" - "@fluentui/react-tabs" "^9.3.24" + "@fluentui/react-skeleton" "^9.0.10" + "@fluentui/react-slider" "^9.1.25" + "@fluentui/react-spinbutton" "^9.2.22" + "@fluentui/react-spinner" "^9.3.1" + "@fluentui/react-switch" "^9.1.25" + "@fluentui/react-table" "^9.6.1" + "@fluentui/react-tabs" "^9.3.25" "@fluentui/react-tabster" "^9.10.0" - "@fluentui/react-text" "^9.3.17" - "@fluentui/react-textarea" "^9.3.21" + "@fluentui/react-text" "^9.3.18" + "@fluentui/react-textarea" "^9.3.22" "@fluentui/react-theme" "^9.1.9" - "@fluentui/react-toast" "^9.0.3" - "@fluentui/react-toolbar" "^9.1.24" - "@fluentui/react-tooltip" "^9.2.23" - "@fluentui/react-tree" "9.0.0-beta.25" + "@fluentui/react-toast" "^9.0.4" + "@fluentui/react-toolbar" "^9.1.25" + "@fluentui/react-tooltip" "^9.2.24" + "@fluentui/react-tree" "9.0.0-beta.26" "@fluentui/react-utilities" "^9.10.1" - "@fluentui/react-virtualizer" "9.0.0-alpha.28" + "@fluentui/react-virtualizer" "9.0.0-alpha.29" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" @@ -1644,17 +1644,17 @@ "@fluentui/react-utilities" "^9.10.1" "@swc/helpers" "^0.4.14" -"@fluentui/react-dialog@^9.5.16": - version "9.5.16" - resolved "https://registry.yarnpkg.com/@fluentui/react-dialog/-/react-dialog-9.5.16.tgz#8c67ceadffbef2802090ea9bf5b33cc726594081" - integrity sha512-3zSKF23Y4/JJ3uqb+R//w5B93CIYsC/jKpqQR8+mHPnmRksCsQwa7BGqABXJoo7+JfGmWWhIDAZCdXmzgyjMCw== +"@fluentui/react-dialog@^9.5.17": + version "9.5.17" + resolved "https://registry.yarnpkg.com/@fluentui/react-dialog/-/react-dialog-9.5.17.tgz#e76484523857015b4b879fb615fca25f8037fc2b" + integrity sha512-ROzYc3ZNvLII8MP2cyiy3eWuXNyRX7t4S67qbOGVfW5apSNTYkmO+QZK3kxh5qp/Izkl6pY7pdlROuuS9CFWBA== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-aria" "^9.3.27" "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-portal" "^9.3.2" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -1662,40 +1662,40 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-divider@^9.2.20": - version "9.2.20" - resolved "https://registry.yarnpkg.com/@fluentui/react-divider/-/react-divider-9.2.20.tgz#5a45af171178c5a1178e8286a586fd56f8a339f2" - integrity sha512-Sb2/VFfCjXPOLqaQHFZaWpaoA31XiNS11tPlrO0Pe5TveOI5ifH2UhIuIVv+0C+Asjn5wmUdZfWaMMCduSJHLw== +"@fluentui/react-divider@^9.2.21": + version "9.2.21" + resolved "https://registry.yarnpkg.com/@fluentui/react-divider/-/react-divider-9.2.21.tgz#ef2de7ef1d6c3d3bece67c93aef1ae89cf679e28" + integrity sha512-SUDOqDnac6YZTDVToNrBCmuOgDil1zGAxm/1wuVbONfJtPWI5egfi6p+tUYmxRmnPsUFo66OWn4TjaOVeDB6Pw== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-drawer@9.0.0-beta.8": - version "9.0.0-beta.8" - resolved "https://registry.yarnpkg.com/@fluentui/react-drawer/-/react-drawer-9.0.0-beta.8.tgz#74d14b946fb5f67fc1b389a67f90aceab754a88d" - integrity sha512-YWCgMX/g/2GZzCEyLFmqk9jhbUYIps/u1mYg9bWiRLd3tAjGEK3mMUDLmtRYaEZn2J1g2DIr1XTP+R9S4VT89A== +"@fluentui/react-drawer@9.0.0-beta.9": + version "9.0.0-beta.9" + resolved "https://registry.yarnpkg.com/@fluentui/react-drawer/-/react-drawer-9.0.0-beta.9.tgz#f6977399386a26bd0084ac06794a72b1747d4d3b" + integrity sha512-8Q+yLanGOUGwAU+Ozo2Sw092d97JqheJppvjB40NMLTGeyGRCQ5Q/U7yonuq+KJk9mOS+t/Oqdk9TklR/2G4Kw== dependencies: - "@fluentui/react-dialog" "^9.5.16" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-dialog" "^9.5.17" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-field@^9.1.11": - version "9.1.11" - resolved "https://registry.yarnpkg.com/@fluentui/react-field/-/react-field-9.1.11.tgz#109335539180919ebb633b57cce0da8bc5eeb781" - integrity sha512-qPcCWURPBVoRClSSTjoLm7E88kEoyzrHoi62L6qoBdY1d3yKXGKDCBOK1j0FsVg5/WECnUDU8T4DO6KRbpUt3g== +"@fluentui/react-field@^9.1.12": + version "9.1.12" + resolved "https://registry.yarnpkg.com/@fluentui/react-field/-/react-field-9.1.12.tgz#59c38485409ead17f6ef65f99dc7101aa31cf072" + integrity sha512-TuXxjIqb8lDlDobez9XaFsbQLLrNkxn5M23to3xULDWZjCUWDptvQIFYRbq+N5iJnlOYohsIG6Q6+mAIxvlM8w== dependencies: "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-label" "^9.1.20" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-label" "^9.1.21" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" @@ -1720,73 +1720,73 @@ "@griffel/react" "^1.0.0" tslib "^2.1.0" -"@fluentui/react-image@^9.1.17": - version "9.1.17" - resolved "https://registry.yarnpkg.com/@fluentui/react-image/-/react-image-9.1.17.tgz#9f0418ca49fa004b96fd8997f8698cd7815eb6fc" - integrity sha512-OgFGv+2a/Isc7gDhl/XNAXVsJONYRqlQ4Ar7UPnlJMUuVQWx1pqXWWD8U41YLcLslds8EkiAH5+SWbnDC7XY8Q== +"@fluentui/react-image@^9.1.18": + version "9.1.18" + resolved "https://registry.yarnpkg.com/@fluentui/react-image/-/react-image-9.1.18.tgz#5ce7801bc6bd203de676dc93a136023f43d9bcdd" + integrity sha512-JF2OXrdd2MBcZXyRCtlSz4tedNGmGQ6Z+Abl+rXxfE0nxgjAFXYXXbGspjQFrYL4W5d02iA1e1SrL5JSsEWN1Q== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-infobutton@9.0.0-beta.42": - version "9.0.0-beta.42" - resolved "https://registry.yarnpkg.com/@fluentui/react-infobutton/-/react-infobutton-9.0.0-beta.42.tgz#e35e6b476dbe5d7e3cee42ce14f92f5b710f8e70" - integrity sha512-3yQBurgNpy06AvezRNhxuXiT9nUDrF62ZV5G7DaTx1o73e7kmO55DQbUKhsDOwyEe+rgKVFFmmW/SZwN/RZQ+w== +"@fluentui/react-infobutton@9.0.0-beta.43": + version "9.0.0-beta.43" + resolved "https://registry.yarnpkg.com/@fluentui/react-infobutton/-/react-infobutton-9.0.0-beta.43.tgz#5a7553d1be6fbb16dc808ea78b7e7abe67d73b3e" + integrity sha512-BHyCqRImDaGBCP5kxTtduxXmj2fzJ+WY1tmtj861LFa8G9D2osRTeMYJltJ/brokLeUW4i4vPSTDx+7wr5sqjA== dependencies: "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-label" "^9.1.20" - "@fluentui/react-popover" "^9.7.6" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-label" "^9.1.21" + "@fluentui/react-popover" "^9.7.7" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-input@^9.4.21": - version "9.4.21" - resolved "https://registry.yarnpkg.com/@fluentui/react-input/-/react-input-9.4.21.tgz#0bea45130dd8c3f75a7a02b1472c6b9161ab1b93" - integrity sha512-Ac1y5z7lnU1F4QeaXdKDkF/vxA3Ioq4jjuTCGOESFSyMQ5PuA2plP30hyke1G/VneLyBb07zI/1OWAk1mkc+IQ== +"@fluentui/react-input@^9.4.22": + version "9.4.22" + resolved "https://registry.yarnpkg.com/@fluentui/react-input/-/react-input-9.4.22.tgz#39514dd6ea9e890ce596e1e5ccfa50b667c29001" + integrity sha512-4TWgBQWmSJYbKN+AHLH1PKE1e5zZ6O/P6WUmTIux/kL6xjsd+2eCIB9HF+dIL8hSWFM7AOklYh0qJo0AWatg+A== dependencies: - "@fluentui/react-field" "^9.1.11" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-field" "^9.1.12" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-jsx-runtime@9.0.0-alpha.11": - version "9.0.0-alpha.11" - resolved "https://registry.yarnpkg.com/@fluentui/react-jsx-runtime/-/react-jsx-runtime-9.0.0-alpha.11.tgz#e84da424f4c8b8d6c8c1df04de62a0392f310188" - integrity sha512-DWX0mSnwXKqIiDE/dE976Qt3ii3covFifMYXQ6v6BdA1cu4foYM5XQioPU12UkDiFiQ2BSavLvZk4aEpXcy/Ew== +"@fluentui/react-jsx-runtime@9.0.0-alpha.12": + version "9.0.0-alpha.12" + resolved "https://registry.yarnpkg.com/@fluentui/react-jsx-runtime/-/react-jsx-runtime-9.0.0-alpha.12.tgz#284889ee8cb456b687b153eb0205812cf9240968" + integrity sha512-902KIzK55KWbJ+2ArMIXUR2OJFnfunwOpTSyDo1N3c3ZMxWeLkHZahyYVmAnXCwQDgnwyR0K8HBjl24gKtNqAw== dependencies: "@fluentui/react-utilities" "^9.10.1" "@swc/helpers" "^0.4.14" -"@fluentui/react-label@^9.1.20": - version "9.1.20" - resolved "https://registry.yarnpkg.com/@fluentui/react-label/-/react-label-9.1.20.tgz#824b116610aa7e50d5b52db85351129666c8a003" - integrity sha512-7lfVhy1pgJSDGc980s2KlAAY3DVkUVdP81nT7Xq9zxkVgHgtmg2FA//03j/mR+1F2P2011pGgvSl8YxtB69+wQ== +"@fluentui/react-label@^9.1.21": + version "9.1.21" + resolved "https://registry.yarnpkg.com/@fluentui/react-label/-/react-label-9.1.21.tgz#a48ee20b791886c34effa43960867a15d8cda136" + integrity sha512-7kr+6IxjOkVRBopMCiuqPQS/bjNuyyIp0w1Dthu8EsQgLkj/fa7Y2A1Ea7Kkmqbsgq+J51U9Rjzd3GKsLxKn0A== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-link@^9.1.2": - version "9.1.2" - resolved "https://registry.yarnpkg.com/@fluentui/react-link/-/react-link-9.1.2.tgz#04e2d48ac0d040b4569c35718ea129047cb0f667" - integrity sha512-QJ/3TtLWvIP06asbhAqE2XE9Y3oH62zyWHtp0XHXR+ljgJNChatVeG9GDhO6CoiJX3lsnR1rwUITY6wAMl2WhA== +"@fluentui/react-link@^9.1.3": + version "9.1.3" + resolved "https://registry.yarnpkg.com/@fluentui/react-link/-/react-link-9.1.3.tgz#845fd843e00dd9f0acefe4653b10ab2df138a454" + integrity sha512-+R7nIjrfYv2yJdE+Iu0Y0QjpqpJQs2AJwbemIgfXYlCWNkgwvFD+22rERwwBHaLBHPC9nsvtIOUpkvwpYeJIFQ== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -1794,17 +1794,17 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-menu@^9.10.0": - version "9.10.0" - resolved "https://registry.yarnpkg.com/@fluentui/react-menu/-/react-menu-9.10.0.tgz#5bb49956e7ed3b04d5232d4ee8dcd08e4a83de44" - integrity sha512-Ri5O8rz36EihLD6bEdnwskWnU8WApAcC2DBVXlztEreTJFfP+fIlofNAhaFsPqn9sDM/idDk3BOnR4VfHyN2sQ== +"@fluentui/react-menu@^9.11.0": + version "9.11.0" + resolved "https://registry.yarnpkg.com/@fluentui/react-menu/-/react-menu-9.11.0.tgz#d58d7372b4126446416d77ba9e35b6280ced623f" + integrity sha512-STk6XTBIDUeuQhr1IFbxfmvmA0SVNiY7L2KTz4fmQmFYMcEJ9Q2N760ygumiFU+68vJesZ+VnVV3phJR1Xw5mw== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-aria" "^9.3.27" "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-portal" "^9.3.2" "@fluentui/react-positioning" "^9.8.0" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" @@ -1882,30 +1882,30 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-persona@^9.2.22": - version "9.2.22" - resolved "https://registry.yarnpkg.com/@fluentui/react-persona/-/react-persona-9.2.22.tgz#c599bdb85f614235abd8d8b824699200e681f997" - integrity sha512-jBD68JqTLBNmmhKLPH9LrJ1FvosYZnkOpK3kGeS1oO1yr76deCoK0VnnxjICMXfSmDQUTD5swvbbkYW8/eyOqw== +"@fluentui/react-persona@^9.2.23": + version "9.2.23" + resolved "https://registry.yarnpkg.com/@fluentui/react-persona/-/react-persona-9.2.23.tgz#1156bad83bdeda5a07c9370e1521207ee25b402e" + integrity sha512-Ezd/BlsjwhcT0K8iX3VvRPdKSafP372HWA+8Wz3wL5Sr7lSkJn1NMykpZcBWorLgwQmn11kO19cR/rTT9yya0g== dependencies: - "@fluentui/react-avatar" "^9.5.12" - "@fluentui/react-badge" "^9.1.20" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-avatar" "^9.5.13" + "@fluentui/react-badge" "^9.1.21" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-popover@^9.7.6": - version "9.7.6" - resolved "https://registry.yarnpkg.com/@fluentui/react-popover/-/react-popover-9.7.6.tgz#77d39c4aea6a3eb40c7a8e65f10090bbabea7475" - integrity sha512-QC+LhWoZ3GFysmcW7ORISYUrGtLJUKPdTHUJE+oM+M8gUSphqfrt4TDBx6H8cjc+KwVa824gpQYlrPjlbM9CKw== +"@fluentui/react-popover@^9.7.7": + version "9.7.7" + resolved "https://registry.yarnpkg.com/@fluentui/react-popover/-/react-popover-9.7.7.tgz#0ebc6ddc9cee4f7c03b22d4e2261c4168a400ca1" + integrity sha512-ebvfml8rPCfXuDr+KNNKMf68ou4C0yNyiMH1poiR53GZWz5iKwvDzYSu+d/DHwI7nxnNDeCvWOx4tCQfwFxvyg== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-aria" "^9.3.27" "@fluentui/react-context-selector" "^9.1.26" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-portal" "^9.3.2" "@fluentui/react-positioning" "^9.8.0" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" @@ -1921,10 +1921,10 @@ dependencies: "@swc/helpers" "^0.4.14" -"@fluentui/react-portal@^9.3.1": - version "9.3.1" - resolved "https://registry.yarnpkg.com/@fluentui/react-portal/-/react-portal-9.3.1.tgz#66bc43a4389c9ba9f1e7e5f824d73cefbc762126" - integrity sha512-jtnX717hr4eFvbPOBmIj8yADN/IKxE+Lk+qlZjoYEy3bdkkmsRAjyhtpAgSU0cpXKKkiGf5eethsFKYbUZxTyA== +"@fluentui/react-portal@^9.3.2": + version "9.3.2" + resolved "https://registry.yarnpkg.com/@fluentui/react-portal/-/react-portal-9.3.2.tgz#77927a9e019e5ec7f018f73edbf081ad24bc969f" + integrity sha512-GDXb3pbNJEbpI8UesYKwvlDNwOjA3SqTSvm4hxfpL5GfxAi+/EPEGgdfOsK09/iPPIbsUqZiD9pQqAHewej3LQ== dependencies: "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" @@ -1945,13 +1945,13 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-progress@^9.1.21": - version "9.1.21" - resolved "https://registry.yarnpkg.com/@fluentui/react-progress/-/react-progress-9.1.21.tgz#e654ba75d0dbe7db916ee4da25be8e5000e8d2c0" - integrity sha512-BAt9JdsEiMM+HcFZUoiwjtiqPiTci88zc47U1bvySgn+fUBhvBEZwdj7FIZwT01+V+ScLKIWkemUNZveSjXrrA== +"@fluentui/react-progress@^9.1.22": + version "9.1.22" + resolved "https://registry.yarnpkg.com/@fluentui/react-progress/-/react-progress-9.1.22.tgz#a775aecc7dfd74bde1c2bf4f0b4184d3b246b73b" + integrity sha512-4Py/KuzwarRoioeqmDvdeB9qFHCnypaHsXr4x4aIosfqgvxfapvM21oeZeP4Q60s0EZzH2uiJAbbYFa7WukAOA== dependencies: - "@fluentui/react-field" "^9.1.11" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-field" "^9.1.12" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" @@ -1967,12 +1967,12 @@ lodash "^4.17.15" prop-types "^15.7.2" -"@fluentui/react-provider@^9.7.9": - version "9.7.9" - resolved "https://registry.yarnpkg.com/@fluentui/react-provider/-/react-provider-9.7.9.tgz#bf11333c19e9388d90a23f0f538f08ac0ce7430c" - integrity sha512-HDRs98kzNQpuW6/XfmtHNSDqSzFqhynIK/3wYbLfd0MOPrg0k2cQ0lVqL7FZyW+xBCHaweiQxT5iWx/SSkazag== +"@fluentui/react-provider@^9.7.10": + version "9.7.10" + resolved "https://registry.yarnpkg.com/@fluentui/react-provider/-/react-provider-9.7.10.tgz#a2104a898974162366fe6f2fc264ed077f21dc9d" + integrity sha512-oUUP/E1/WSTbj4o4HUmO2HCdBgrwJHsMGrKPXQ0DYJmTcF72FkZDE7bQJSZ2h0Tu3ZdgTVVib55btKaEOngEcQ== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -1981,15 +1981,15 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-radio@^9.1.24": - version "9.1.24" - resolved "https://registry.yarnpkg.com/@fluentui/react-radio/-/react-radio-9.1.24.tgz#35e241ee472ca9368b948986ea44e31634244200" - integrity sha512-b5k405bo2TfFgr5vPiRjMrEIBu2Hcnmif/lmKxkuf9UlKxu+7YzPCEg5ThqIUauj1J4ssVRrM3GoFE6WSqmCVQ== +"@fluentui/react-radio@^9.1.25": + version "9.1.25" + resolved "https://registry.yarnpkg.com/@fluentui/react-radio/-/react-radio-9.1.25.tgz#c8c0cfdab32aa78a889ea969f4595b4655d6dd33" + integrity sha512-bNs9DelAO+3iAYNZ6BjLal9oH5qwyph5m4g1aVsSYzTKcFWIm+Um8AWb5dEN8ZQLIZQaGjCNv/rYunOoZOxNjQ== dependencies: - "@fluentui/react-field" "^9.1.11" + "@fluentui/react-field" "^9.1.12" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-label" "^9.1.20" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-label" "^9.1.21" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -1997,14 +1997,14 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-select@^9.1.21": - version "9.1.21" - resolved "https://registry.yarnpkg.com/@fluentui/react-select/-/react-select-9.1.21.tgz#420ee0752ae1a54c86e3fdc4b14787d3dede311b" - integrity sha512-5K2KlGzEhfAO0iCwpPPCZn36ATEATt+h0NJ29ZklhRMlSql79WkJ/CKgsEJr4vGOeLRdj2iPdaYdSG7pgGz+jA== +"@fluentui/react-select@^9.1.22": + version "9.1.22" + resolved "https://registry.yarnpkg.com/@fluentui/react-select/-/react-select-9.1.22.tgz#d647c8eba45748e9042fd0de89b954e4d34b6578" + integrity sha512-McfmVMSwF6O+HRvIn4gJ5sGjlQeqwrXdjTSvSmzWloyfc6lyBvkGd38Pgg0044VyFofHMDPW4yd96JA/RTxMTQ== dependencies: - "@fluentui/react-field" "^9.1.11" + "@fluentui/react-field" "^9.1.12" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" @@ -2019,26 +2019,26 @@ "@fluentui/react-theme" "^9.1.9" "@swc/helpers" "^0.4.14" -"@fluentui/react-skeleton@^9.0.9": - version "9.0.9" - resolved "https://registry.yarnpkg.com/@fluentui/react-skeleton/-/react-skeleton-9.0.9.tgz#3de3934af544de5206208e7c50f5fd4a560dbd6d" - integrity sha512-f361g2t8uthwNuITJLOtRvCbjoveqYTiYhzd0oKwPZlHkz9xZizVnOLYSXFYyMXAOt4F8Ib4sbdSFjNHycAG2A== +"@fluentui/react-skeleton@^9.0.10": + version "9.0.10" + resolved "https://registry.yarnpkg.com/@fluentui/react-skeleton/-/react-skeleton-9.0.10.tgz#38f0fc48cef7e4ab817c1c514a24303d73d06549" + integrity sha512-c0E9NUrCp2KFC1TmOZw6Gv7ED1YIFoyGBBrxU23oOJtPPOrsTP6CHQPuJt8yRFbDbdleNUYJ22SzP66YT+onfw== dependencies: - "@fluentui/react-field" "^9.1.11" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-field" "^9.1.12" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-slider@^9.1.24": - version "9.1.24" - resolved "https://registry.yarnpkg.com/@fluentui/react-slider/-/react-slider-9.1.24.tgz#6f745ceb38dfbff0354b353db7f1c553e1bface4" - integrity sha512-2aukES7cnh/8UvHR3QhE1zM69emkap0GwuZiwgzia6Rj2oD4N24ZNFFNtCtpDc/L8KKNy9Tut5I/klP0tohD3w== +"@fluentui/react-slider@^9.1.25": + version "9.1.25" + resolved "https://registry.yarnpkg.com/@fluentui/react-slider/-/react-slider-9.1.25.tgz#b8680c933b795199603eaa9227f51b5bc75e5192" + integrity sha512-xiqtxZBIETfpllGDiqCrzoqAb/DoFDgVWRE/jlfBImNogyNZEw2+W+rwMXGqtAqWBD76lXOh7PxZW2uep7ia7A== dependencies: - "@fluentui/react-field" "^9.1.11" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-field" "^9.1.12" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -2046,43 +2046,43 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-spinbutton@^9.2.21": - version "9.2.21" - resolved "https://registry.yarnpkg.com/@fluentui/react-spinbutton/-/react-spinbutton-9.2.21.tgz#21a7b04fa04609d58f362763a897568af2ed7da9" - integrity sha512-A+qy6fb52Kr16slC+UduZAFhee8Y2HVopepIvujgHoxWx4qvdjIjrlYsQMiat9g+/Fj6e17f2oS3gLF9h9/cpA== +"@fluentui/react-spinbutton@^9.2.22": + version "9.2.22" + resolved "https://registry.yarnpkg.com/@fluentui/react-spinbutton/-/react-spinbutton-9.2.22.tgz#391b2d1e4c3a0174cc1e01bbc774e5a7dcf84611" + integrity sha512-gKQGcR5bFsPMatxMHQ9hecTr7EyOVOa76+ozk511VzE1bZtfX66Pm8qaKyiy3ZOHcTRmvgwF2lGOGQyz344qOQ== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-field" "^9.1.11" + "@fluentui/react-field" "^9.1.12" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-spinner@^9.3.0": - version "9.3.0" - resolved "https://registry.yarnpkg.com/@fluentui/react-spinner/-/react-spinner-9.3.0.tgz#e1f2eb2b0f764370edc2d179926cd2bdb1fd3324" - integrity sha512-7kakV+ujPo249zqhg2AJG0yFZjyiSVHmPq3QjeHtxC7SETTsYrrK1fPTzj3zl9lO+194X1rmYLPcxo1PKEN26g== +"@fluentui/react-spinner@^9.3.1": + version "9.3.1" + resolved "https://registry.yarnpkg.com/@fluentui/react-spinner/-/react-spinner-9.3.1.tgz#acc76141d061a49b8f5a8e298dba84716d244b9e" + integrity sha512-hOlAjALWqpaiyd2GOwTpbsntSwXzbhMRVE2Mnd7MIy5j5GqN/29IWRTXR5D2P6svQiMkgNh5R1qToV05DobrYg== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-label" "^9.1.20" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-label" "^9.1.21" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-switch@^9.1.24": - version "9.1.24" - resolved "https://registry.yarnpkg.com/@fluentui/react-switch/-/react-switch-9.1.24.tgz#2302373282dc9af4fa5dae3f36e575028e42e8ed" - integrity sha512-FSeQDOGzDERmStDjGr7NO/wQsd4VG7mI6nWYJcK5qIg7TZFFsa8snf8uknL8irf7c5sSfaUDj8DUVcxRq9nH4w== +"@fluentui/react-switch@^9.1.25": + version "9.1.25" + resolved "https://registry.yarnpkg.com/@fluentui/react-switch/-/react-switch-9.1.25.tgz#11aced65f4389fd64520424c3cfd6f4489d0f1c8" + integrity sha512-BLQINtFzEU1Tv4XDVFYxS9jtCXt9dwIQIcOFUVpg0MxzUoRbrUjwpBQjQkdQzMww62OAQzKkN3gCksN59jBhEg== dependencies: - "@fluentui/react-field" "^9.1.11" + "@fluentui/react-field" "^9.1.12" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-label" "^9.1.20" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-label" "^9.1.21" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -2090,19 +2090,19 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-table@^9.6.0": - version "9.6.0" - resolved "https://registry.yarnpkg.com/@fluentui/react-table/-/react-table-9.6.0.tgz#9ebb0a23fc4268c77dccc80f1eef4971b6d16a21" - integrity sha512-HVJoHvM8k7SkOjuP7aBLpDeoQhtzn2Skh4O9bCDMNaxoHmcgPw9zskt2Kau/wXSx2JyrGGEz707yRb6EgpKlJg== +"@fluentui/react-table@^9.6.1": + version "9.6.1" + resolved "https://registry.yarnpkg.com/@fluentui/react-table/-/react-table-9.6.1.tgz#3b89981d77216478dd80bfd82aa1122ceaf5c5c8" + integrity sha512-hhw27B4edudF0ti5tHjxZOETjresmTJYBXiLOiFGiAcMONs78Oklaw6NjDPKRoBoLmyEBE5PpjGkDP5nppUelg== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.26" - "@fluentui/react-avatar" "^9.5.12" - "@fluentui/react-checkbox" "^9.1.24" + "@fluentui/react-aria" "^9.3.27" + "@fluentui/react-avatar" "^9.5.13" + "@fluentui/react-checkbox" "^9.1.25" "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-radio" "^9.1.24" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-radio" "^9.1.25" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -2110,13 +2110,13 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-tabs@^9.3.24": - version "9.3.24" - resolved "https://registry.yarnpkg.com/@fluentui/react-tabs/-/react-tabs-9.3.24.tgz#c39bce6d8cd462c304e41feb644ae9b2fe00004a" - integrity sha512-5gbGcdJV8zvn6XNesniMrlcgLJhcfcpcGXNA/98vb90Kkhe6MSNp9p7dpVVgnhquJ5MZMVLO9OI8Jj1ugU04jQ== +"@fluentui/react-tabs@^9.3.25": + version "9.3.25" + resolved "https://registry.yarnpkg.com/@fluentui/react-tabs/-/react-tabs-9.3.25.tgz#c622a969306f2c21e8b847552819e7332f992968" + integrity sha512-WMEDGQxtlhLpt0/mw2RKKwrHuS8eLYNxukBEyd5a/tVHYU+X6YzCoafBRQ8aeXCAqYf24cHXDJmAPEZwYUribw== dependencies: "@fluentui/react-context-selector" "^9.1.26" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -2137,25 +2137,25 @@ keyborg "^2.0.0" tabster "^4.5.1" -"@fluentui/react-text@^9.3.17": - version "9.3.17" - resolved "https://registry.yarnpkg.com/@fluentui/react-text/-/react-text-9.3.17.tgz#aaeb56ad6be2c6c727e7f08dbc7dc35a1da69b1e" - integrity sha512-d/fORzmZ3H2n+Ki5nBkA7fvUa+ReOsk3GVxRB0brAmHaO/7nesi7DjnCTw4owv2vkVwXQJfhT7STxAc6TYjkQw== +"@fluentui/react-text@^9.3.18": + version "9.3.18" + resolved "https://registry.yarnpkg.com/@fluentui/react-text/-/react-text-9.3.18.tgz#f3f52c1afeb0915dd0da98413b11cc769fff5f04" + integrity sha512-kXMA6CEKoqGTASAr84SRPf6o1//8qAOCGUzW5Ut+wkTtKqIX0dghogEP9vd8zpQWRSSG0OAxOx25rXO8ysMvJw== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-textarea@^9.3.21": - version "9.3.21" - resolved "https://registry.yarnpkg.com/@fluentui/react-textarea/-/react-textarea-9.3.21.tgz#d1c097ca06c2fb03355e0d60d6184d824afed7cc" - integrity sha512-17w3ZdWiysWDp3TLoq72lvNvR3BDmMcjGje3+G0ns+pReqK/CdHl0gTIgiQsPNyWFtck/zDdQ/gfxNND/LXoLw== +"@fluentui/react-textarea@^9.3.22": + version "9.3.22" + resolved "https://registry.yarnpkg.com/@fluentui/react-textarea/-/react-textarea-9.3.22.tgz#135e15b4895e1591be8e60aae46d1eaf987d77a8" + integrity sha512-wNOq8HVlARQYVy7T/EQD0s3iFtV57be/z37z52rjxV74P02IguJDiAmQLpHEXv+IB1ysa1kW1xEyFwInExIUIw== dependencies: - "@fluentui/react-field" "^9.1.11" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-field" "^9.1.12" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" "@fluentui/react-utilities" "^9.10.1" @@ -2170,15 +2170,15 @@ "@fluentui/tokens" "1.0.0-alpha.6" "@swc/helpers" "^0.4.14" -"@fluentui/react-toast@^9.0.3": - version "9.0.3" - resolved "https://registry.yarnpkg.com/@fluentui/react-toast/-/react-toast-9.0.3.tgz#d0c42612c98cfb4e5a51386f3dd1dcce4aad1989" - integrity sha512-lOwaTwL0xDQhzqCmtvDlm3AcUoHvL8ihlHMbvtylzBlIUigwmwEJF1fUtYIYXiRZoTnjOwPWWhQpbyA4OoVmUw== +"@fluentui/react-toast@^9.0.4": + version "9.0.4" + resolved "https://registry.yarnpkg.com/@fluentui/react-toast/-/react-toast-9.0.4.tgz#609b946c43a32d56d48a1f504904d270d8acf3cf" + integrity sha512-Po8qLZX2mkALVWfyKyk2r7USkSAlMj9JmrcCSAcVN1X0dXeheITDtcavJdeoL55FS5d2q8x8My3fZ6UXldZ6Dg== dependencies: - "@fluentui/react-aria" "^9.3.26" + "@fluentui/react-aria" "^9.3.27" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-portal" "^9.3.2" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -2187,16 +2187,16 @@ "@swc/helpers" "^0.4.14" react-transition-group "^4.4.1" -"@fluentui/react-toolbar@^9.1.24": - version "9.1.24" - resolved "https://registry.yarnpkg.com/@fluentui/react-toolbar/-/react-toolbar-9.1.24.tgz#d81b7e3cb6be4cee23bccd6aa2320d6fdfb4a035" - integrity sha512-RDRQBDv0LoNUU3Zq8dwQ/SzwjFockf7Ndgxttz8YIxi1vkEOGRvorichV10vhaedbA5PEo6c9m2mxkUR2QO3YQ== +"@fluentui/react-toolbar@^9.1.25": + version "9.1.25" + resolved "https://registry.yarnpkg.com/@fluentui/react-toolbar/-/react-toolbar-9.1.25.tgz#dacaa2fe6473550e32eda7751c3977f5a264fc93" + integrity sha512-N1jB+fNgnvK5J0pbT/lF9QTrHn9Bo6BbMypIczJGbFgrTwZQCUNVKgLyeiK12nfd/1pTy6DreS1iuaMk+ir6Ow== dependencies: - "@fluentui/react-button" "^9.3.23" + "@fluentui/react-button" "^9.3.24" "@fluentui/react-context-selector" "^9.1.26" - "@fluentui/react-divider" "^9.2.20" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-radio" "^9.1.24" + "@fluentui/react-divider" "^9.2.21" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-radio" "^9.1.25" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -2204,14 +2204,14 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-tooltip@^9.2.23": - version "9.2.23" - resolved "https://registry.yarnpkg.com/@fluentui/react-tooltip/-/react-tooltip-9.2.23.tgz#03212459ccb2945d735aacbb990a33358a83ccec" - integrity sha512-CKwJwi7kgrRYTdaL5G+A56/GHfCVJzCHHtamHzoxEhKeFDoGDy/pGH0rcneR3Jzgthf35TLyJTYO+EWVZvdTWQ== +"@fluentui/react-tooltip@^9.2.24": + version "9.2.24" + resolved "https://registry.yarnpkg.com/@fluentui/react-tooltip/-/react-tooltip-9.2.24.tgz#0794b4ca29a5c21ab9d9b9cd04455b5f3465c5a5" + integrity sha512-CTA9kk+X2itc3X6VvNEtW4zVN3jpPJhAmng6FHgIYDyspw5Wsc96KSJGsogUrRyPNNUVnTKBHYsYtEefPuGVmQ== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-portal" "^9.3.2" "@fluentui/react-positioning" "^9.8.0" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-theme" "^9.1.9" @@ -2219,19 +2219,21 @@ "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" -"@fluentui/react-tree@9.0.0-beta.25": - version "9.0.0-beta.25" - resolved "https://registry.yarnpkg.com/@fluentui/react-tree/-/react-tree-9.0.0-beta.25.tgz#e06f125829837b39cbf69a2438800e2e4574f702" - integrity sha512-T2l0WE4rBBl/CyhTxtxTw/7LuxtmmMBfQ8upaRiHfgigXme2ss1pcQF7mkGhRl2WSxOLeWEHVX1XTdgWhuZp/A== +"@fluentui/react-tree@9.0.0-beta.26": + version "9.0.0-beta.26" + resolved "https://registry.yarnpkg.com/@fluentui/react-tree/-/react-tree-9.0.0-beta.26.tgz#9b6770e83248827c0e61fa0a084519598c80cde4" + integrity sha512-xKbDdNrvR+iuhuzWE5FNQjbAjf8TnP2J7h9Od4G6R0/BnNzIjOPc2NGBWdF/ohnhDR7So5vip7+g3oJ9YOBvFA== dependencies: "@fluentui/keyboard-keys" "^9.0.3" - "@fluentui/react-aria" "^9.3.26" - "@fluentui/react-avatar" "^9.5.12" - "@fluentui/react-button" "^9.3.23" + "@fluentui/react-aria" "^9.3.27" + "@fluentui/react-avatar" "^9.5.13" + "@fluentui/react-button" "^9.3.24" + "@fluentui/react-checkbox" "^9.1.25" "@fluentui/react-context-selector" "^9.1.26" "@fluentui/react-icons" "^2.0.203" - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" - "@fluentui/react-portal" "^9.3.1" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" + "@fluentui/react-portal" "^9.3.2" + "@fluentui/react-radio" "^9.1.25" "@fluentui/react-shared-contexts" "^9.6.0" "@fluentui/react-tabster" "^9.10.0" "@fluentui/react-theme" "^9.1.9" @@ -2247,12 +2249,12 @@ "@fluentui/keyboard-keys" "^9.0.3" "@swc/helpers" "^0.4.14" -"@fluentui/react-virtualizer@9.0.0-alpha.28": - version "9.0.0-alpha.28" - resolved "https://registry.yarnpkg.com/@fluentui/react-virtualizer/-/react-virtualizer-9.0.0-alpha.28.tgz#b0f2960fd45ebd73f28fdb4a7afcd4466676cd33" - integrity sha512-jqysw3feXlQT0aS+TFTtmS4wtDkCmGbvywXyiPaKFYF1RvA34UXJbxrgB7RXAey6xMPBxwM6tj3Om6/gPiGg+Q== +"@fluentui/react-virtualizer@9.0.0-alpha.29": + version "9.0.0-alpha.29" + resolved "https://registry.yarnpkg.com/@fluentui/react-virtualizer/-/react-virtualizer-9.0.0-alpha.29.tgz#a381731d9d2661761a19ca1ea23db41e05030714" + integrity sha512-cwNKwrej47AUZrd+OoKSDo+h5oyZ5+0P9FjvuRYXPPxuiGT2XI6cG7g2LKcRRuLmCTplrdEZ2GHX6UxD7bHKEA== dependencies: - "@fluentui/react-jsx-runtime" "9.0.0-alpha.11" + "@fluentui/react-jsx-runtime" "9.0.0-alpha.12" "@fluentui/react-utilities" "^9.10.1" "@griffel/react" "^1.5.7" "@swc/helpers" "^0.4.14" From f0ccedf6c83020a02e7b7dcc4d412d255e1948e8 Mon Sep 17 00:00:00 2001 From: Ben Thomas Date: Mon, 24 Jul 2023 16:15:18 -0700 Subject: [PATCH 012/582] Setting up CI/CD pipeline to cancel when a new push happens. (#24) ### Motivation and Context When something is pushed to main we trigger the deployment to our int environment. If a new push happens when the pipeline is already running, the current run should be canceled. ### Description Setting up CI/CD pipeline to cancel when a new push happens. ### Contribution Checklist - [x] The code builds clean without any errors or warnings - [x] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone :smile: Co-authored-by: Ben Thomas --- .github/workflows/copilot-deploy-pipeline.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/copilot-deploy-pipeline.yml b/.github/workflows/copilot-deploy-pipeline.yml index f4a88e4af..37dc3b540 100644 --- a/.github/workflows/copilot-deploy-pipeline.yml +++ b/.github/workflows/copilot-deploy-pipeline.yml @@ -5,6 +5,10 @@ on: push: branches: ["main"] +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: true + permissions: contents: read id-token: write From 0f99a79b7d4d3531455132a16fb60168df21a9f1 Mon Sep 17 00:00:00 2001 From: Gil LaHaye Date: Mon, 24 Jul 2023 17:17:04 -0600 Subject: [PATCH 013/582] Make templates support Azure Cognitive Search (#16) ### Motivation and Context We want the deployment templates support ACS ### Description Augment the templates so that they support ACS in addition to Qdrant for storage of embeddings ### Contribution Checklist - [ ] The code builds clean without any errors or warnings - [ ] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone :smile: --- README.md | 3 +- deploy/deploy-azure.ps1 | 11 ++++--- deploy/deploy-azure.sh | 13 ++++---- deploy/deploy-webapp.ps1 | 23 +++++++------- deploy/deploy-webapp.sh | 8 ++--- deploy/main.bicep | 49 ++++++++++++++++++++++------ deploy/main.json | 69 ++++++++++++++++++++++++++++++---------- 7 files changed, 122 insertions(+), 54 deletions(-) diff --git a/README.md b/README.md index bb20fc54b..f364113ac 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,8 @@ # About Chat Copilot -This sample allows you to build your own integrated large language model chat copilot that is powered by [semantic-kernel](https://github.com/microsoft/semantic-kernel). +This sample allows you to build your own integrated large language model chat copilot that is +powered by [Semantic Kernel](https://github.com/microsoft/semantic-kernel). This is an enriched intelligence app, with multiple dynamic components including command messages, user intent, and memories. diff --git a/deploy/deploy-azure.ps1 b/deploy/deploy-azure.ps1 index a2757412a..8416b5c6a 100644 --- a/deploy/deploy-azure.ps1 +++ b/deploy/deploy-azure.ps1 @@ -34,15 +34,16 @@ param( [string] # Region to which to make the deployment (ignored when deploying to an existing resource group) - $Region = "centralus", + $Region = "southcentralus", [string] # SKU for the Azure App Service plan $WebAppServiceSku = "B1", - [switch] - # Don't deploy Qdrant for memory storage - Use volatile memory instead - $NoQdrant, + [ValidateSet("Volatile", "AzureCognitiveSearch", "Qdrant")] + [string] + # What method to use to persist embeddings + $MemoryStore = "AzureCognitiveSearch", [switch] # Don't deploy Cosmos DB for chat storage - Use volatile memory instead @@ -89,7 +90,7 @@ $jsonConfig = " `\`"aiApiKey`\`": { `\`"value`\`": `\`"$AIApiKey`\`" }, `\`"aiEndpoint`\`": { `\`"value`\`": `\`"$AIEndpoint`\`" }, `\`"deployNewAzureOpenAI`\`": { `\`"value`\`": $(If ($DeployAzureOpenAI) {"true"} Else {"false"}) }, - `\`"deployQdrant`\`": { `\`"value`\`": $(If (!($NoQdrant)) {"true"} Else {"false"}) }, + `\`"memoryStore`\`": { `\`"value`\`": `\`"$MemoryStore`\`" }, `\`"deployCosmosDB`\`": { `\`"value`\`": $(If (!($NoCosmosDb)) {"true"} Else {"false"}) }, `\`"deploySpeechServices`\`": { `\`"value`\`": $(If (!($NoSpeechServices)) {"true"} Else {"false"}) } } diff --git a/deploy/deploy-azure.sh b/deploy/deploy-azure.sh index d5a2f639c..50a8b0967 100755 --- a/deploy/deploy-azure.sh +++ b/deploy/deploy-azure.sh @@ -17,7 +17,8 @@ usage() { echo " -rg, --resource-group RESOURCE_GROUP Resource group to which to make the deployment (default: \"rg-\$DEPLOYMENT_NAME\")" echo " -r, --region REGION Region to which to make the deployment (default: \"South Central US\")" echo " -a, --app-service-sku WEB_APP_SVC_SKU SKU for the Azure App Service plan (default: \"B1\")" - echo " -nq, --no-qdrant Don't deploy Qdrant for memory storage - Use volatile memory instead" + echo " -ms, --memory-store Method to use to persist embeddings. Valid values are" + echo " \"AzureCognitiveSearch\" (default), \"Qdrant\" and \"Volatile\"" echo " -nc, --no-cosmos-db Don't deploy Cosmos DB for chat storage - Use volatile memory instead" echo " -ns, --no-speech-services Don't deploy Speech Services to enable speech as chat input" echo " -dd, --debug-deployment Switches on verbose template deployment output" @@ -73,8 +74,8 @@ while [[ $# -gt 0 ]]; do shift shift ;; - -nq|--no-qdrant) - NO_QDRANT=true + -ms|--memory-store) + MEMORY_STORE=="$2" shift ;; -nc|--no-cosmos-db) @@ -161,9 +162,9 @@ fi az account set -s "$SUBSCRIPTION" # Set defaults -: "${REGION:="centralus"}" +: "${REGION:="southcentralus"}" : "${WEB_APP_SVC_SKU:="B1"}" -: "${NO_QDRANT:=false}" +: "${MEMORY_STORE:="AzureCognitiveSearch"}" : "${NO_COSMOS_DB:=false}" : "${NO_SPEECH_SERVICES:=false}" @@ -177,7 +178,7 @@ JSON_CONFIG=$(cat << EOF "deployWebApiPackage": { "value": $([ "$NO_DEPLOY_PACKAGE" = true ] && echo "false" || echo "true") }, "aiEndpoint": { "value": "$([ ! -z "$AI_ENDPOINT" ] && echo "$AI_ENDPOINT")" }, "deployNewAzureOpenAI": { "value": $([ "$NO_NEW_AZURE_OPENAI" = true ] && echo "false" || echo "true") }, - "deployQdrant": { "value": $([ "$NO_QDRANT" = true ] && echo "false" || echo "true") }, + "memoryStore": { "value": "$MEMORY_STORE" }, "deployCosmosDB": { "value": $([ "$NO_COSMOS_DB" = true ] && echo "false" || echo "true") }, "deploySpeechServices": { "value": $([ "$NO_SPEECH_SERVICES" = true ] && echo "false" || echo "true") } } diff --git a/deploy/deploy-webapp.ps1 b/deploy/deploy-webapp.ps1 index 14fc44f0a..dd05a520b 100644 --- a/deploy/deploy-webapp.ps1 +++ b/deploy/deploy-webapp.ps1 @@ -13,15 +13,15 @@ param( [string] # Resource group to which to make the deployment $ResourceGroupName, - + [Parameter(Mandatory)] [string] - # Name of the previously deployed Azure deployment + # Name of the previously deployed Azure deployment $DeploymentName, [Parameter(Mandatory)] [string] - # Client application id + # Client application id $ApplicationClientId, [Parameter(Mandatory=$false)] @@ -55,7 +55,7 @@ Write-Host "webappName: $webappName" Write-Host "webapiName: $webapiName" Write-Host "webapiUrl: $webapiUrl" -# Set UTF8 as default encoding for Out-File +# Set ASCII as default encoding for Out-File $PSDefaultParameterValues['Out-File:Encoding'] = 'ascii' $envFilePath = "$PSScriptRoot/../webapp/.env" @@ -66,11 +66,11 @@ Write-Host "Writing environment variables to '$envFilePath'..." "REACT_APP_SK_API_KEY=$webapiApiKey" | Out-File -FilePath $envFilePath -Append Write-Host "Generating SWA config..." -$swaConfig = $(Get-Content "$PSScriptRoot/../webapp/template.swa-cli.config.json" -Raw) -$swaConfig = $swaConfig.Replace("{{appDevserverUrl}}", "https://$webappUrl") -$swaConfig = $swaConfig.Replace("{{appName}}", "$webappName") -$swaConfig = $swaConfig.Replace("{{resourceGroup}}", "$ResourceGroupName") -$swaConfig = $swaConfig.Replace("{{subscription-id}}", "$Subscription") +$swaConfig = $(Get-Content "$PSScriptRoot/../webapp/template.swa-cli.config.json" -Raw) +$swaConfig = $swaConfig.Replace("{{appDevserverUrl}}", "https://$webappUrl") +$swaConfig = $swaConfig.Replace("{{appName}}", "$webappName") +$swaConfig = $swaConfig.Replace("{{resourceGroup}}", "$ResourceGroupName") +$swaConfig = $swaConfig.Replace("{{subscription-id}}", "$Subscription") $swaConfig | Out-File -FilePath "$PSScriptRoot/../webapp/swa-cli.config.json" Write-Host $(Get-Content "$PSScriptRoot/../webapp/swa-cli.config.json" -Raw) @@ -94,8 +94,10 @@ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } +Pop-Location + $origin = "https://$webappUrl" -Write-Host "Ensuring CORS origin '$origin' to webapi '$webapiName'..." +Write-Host "Ensuring '$origin' is included in CORS origins for webapi '$webapiName'..." if (-not ((az webapp cors show --name $webapiName --resource-group $ResourceGroupName --subscription $Subscription | ConvertFrom-Json).allowedOrigins -contains $origin)) { az webapp cors add --name $webapiName --resource-group $ResourceGroupName --subscription $Subscription --allowed-origins $origin } @@ -122,6 +124,5 @@ if ($LASTEXITCODE -ne 0) { exit $LASTEXITCODE } -Pop-Location Write-Host "To verify your deployment, go to 'https://$webappUrl' in your browser." diff --git a/deploy/deploy-webapp.sh b/deploy/deploy-webapp.sh index 69c7ea6bb..2828f6872 100755 --- a/deploy/deploy-webapp.sh +++ b/deploy/deploy-webapp.sh @@ -131,10 +131,12 @@ if [ $? -ne 0 ]; then exit 1 fi +popd + ORIGIN="https://$WEB_APP_URL" -echo "Ensuring CORS origin '$ORIGIN' to webapi '$WEB_API_NAME'..." +echo "Ensuring origin '$ORIGIN' is included in CORS origins for webapi '$WEB_API_NAME'..." CORS_RESULT=$(az webapp cors show --name $WEB_API_NAME --resource-group $RESOURCE_GROUP --subscription $SUBSCRIPTION | jq '.allowedOrigins | index("$ORIGIN")') -if [[ "$CORS_RESULT" == "null" ]]; then +if [[ "$CORS_RESULT" == "null" ]]; then echo "Adding CORS origin '$ORIGIN' to webapi '$WEB_API_NAME'..." az webapp cors add --name $WEB_API_NAME --resource-group $RESOURCE_GROUP --subscription $SUBSCRIPTION --allowed-origins $ORIGIN fi @@ -161,6 +163,4 @@ if [ "$NO_REDIRECT" != true ]; then fi fi -popd - echo "To verify your deployment, go to 'https://$WEB_APP_URL' in your browser." \ No newline at end of file diff --git a/deploy/main.bicep b/deploy/main.bicep index 7a3261fa3..c07259108 100644 --- a/deploy/main.bicep +++ b/deploy/main.bicep @@ -49,8 +49,13 @@ param deployNewAzureOpenAI bool = false @description('Whether to deploy Cosmos DB for persistent chat storage') param deployCosmosDB bool = true -@description('Whether to deploy Qdrant (in a container) for persistent memory storage') -param deployQdrant bool = true +@description('What method to use to persist embeddings') +@allowed([ + 'Volatile' + 'AzureCognitiveSearch' + 'Qdrant' +]) +param memoryStore string = 'Volatile' @description('Whether to deploy Azure Speech Services to enable input by voice') param deploySpeechServices bool = true @@ -223,16 +228,28 @@ resource appServiceWebConfig 'Microsoft.Web/sites/config@2022-09-01' = { } { name: 'MemoriesStore:Type' - value: deployQdrant ? 'Qdrant' : 'Volatile' + value: memoryStore } { name: 'MemoriesStore:Qdrant:Host' - value: deployQdrant ? 'https://${appServiceQdrant.properties.defaultHostName}' : '' + value: memoryStore == 'Qdrant' ? 'https://${appServiceQdrant.properties.defaultHostName}' : '' } { name: 'MemoriesStore:Qdrant:Port' value: '443' } + { + name: 'MemoriesStore:AzureCognitiveSearch:UseVectorSearch' + value: 'true' + } + { + name: 'MemoriesStore:AzureCognitiveSearch:Endpoint' + value: memoryStore == 'AzureCognitiveSearch' ? 'https://${azureCognitiveSearch.name}.search.windows.net' : '' + } + { + name: 'MemoriesStore:AzureCognitiveSearch:Key' + value: memoryStore == 'AzureCognitiveSearch' ? azureCognitiveSearch.listAdminKeys().primaryKey : '' + } { name: 'AzureSpeech:Region' value: location @@ -335,7 +352,7 @@ resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2022-10 } } -resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' = if (deployQdrant) { +resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' = if (memoryStore == 'Qdrant') { name: 'st${rgIdHash}' // Not using full unique name to avoid hitting 24 char limit location: location kind: 'StorageV2' @@ -354,7 +371,7 @@ resource storage 'Microsoft.Storage/storageAccounts@2022-09-01' = if (deployQdra } } -resource appServicePlanQdrant 'Microsoft.Web/serverfarms@2022-03-01' = if (deployQdrant) { +resource appServicePlanQdrant 'Microsoft.Web/serverfarms@2022-03-01' = if (memoryStore == 'Qdrant') { name: 'asp-${uniqueName}-qdrant' location: location kind: 'linux' @@ -366,7 +383,7 @@ resource appServicePlanQdrant 'Microsoft.Web/serverfarms@2022-03-01' = if (deplo } } -resource appServiceQdrant 'Microsoft.Web/sites@2022-09-01' = if (deployQdrant) { +resource appServiceQdrant 'Microsoft.Web/sites@2022-09-01' = if (memoryStore == 'Qdrant') { name: 'app-${uniqueName}-qdrant' location: location kind: 'app,linux,container' @@ -398,16 +415,28 @@ resource appServiceQdrant 'Microsoft.Web/sites@2022-09-01' = if (deployQdrant) { azureStorageAccounts: { aciqdrantshare: { type: 'AzureFiles' - accountName: deployQdrant ? storage.name : 'notdeployed' + accountName: memoryStore == 'Qdrant' ? storage.name : 'notdeployed' shareName: storageFileShareName mountPath: '/qdrant/storage' - accessKey: deployQdrant ? storage.listKeys().keys[0].value : '' + accessKey: memoryStore == 'Qdrant' ? storage.listKeys().keys[0].value : '' } } } } } +resource azureCognitiveSearch 'Microsoft.Search/searchServices@2022-09-01' = if (memoryStore == 'AzureCognitiveSearch') { + name: 'acs-${uniqueName}' + location: location + sku: { + name: 'basic' + } + properties: { + replicaCount: 1 + partitionCount: 1 + } +} + resource virtualNetwork 'Microsoft.Network/virtualNetworks@2021-05-01' = { name: 'vnet-${uniqueName}' location: location @@ -515,7 +544,7 @@ resource webSubnetConnection 'Microsoft.Web/sites/virtualNetworkConnections@2022 } } -resource qdrantSubnetConnection 'Microsoft.Web/sites/virtualNetworkConnections@2022-09-01' = if (deployQdrant) { +resource qdrantSubnetConnection 'Microsoft.Web/sites/virtualNetworkConnections@2022-09-01' = if (memoryStore == 'Qdrant') { parent: appServiceQdrant name: 'qdrantSubnetConnection' properties: { diff --git a/deploy/main.json b/deploy/main.json index 9ab7c188e..b059692f8 100644 --- a/deploy/main.json +++ b/deploy/main.json @@ -5,7 +5,7 @@ "_generator": { "name": "bicep", "version": "0.19.5.34762", - "templateHash": "5601121958092657135" + "templateHash": "12182074692341112389" } }, "parameters": { @@ -107,11 +107,16 @@ "description": "Whether to deploy Cosmos DB for persistent chat storage" } }, - "deployQdrant": { - "type": "bool", - "defaultValue": true, + "memoryStore": { + "type": "string", + "defaultValue": "Volatile", + "allowedValues": [ + "Volatile", + "AzureCognitiveSearch", + "Qdrant" + ], "metadata": { - "description": "Whether to deploy Qdrant (in a container) for persistent memory storage" + "description": "What method to use to persist embeddings" } }, "deploySpeechServices": { @@ -150,7 +155,7 @@ }, "resources": [ { - "condition": "[parameters('deployQdrant')]", + "condition": "[equals(parameters('memoryStore'), 'Qdrant')]", "type": "Microsoft.Storage/storageAccounts/fileServices/shares", "apiVersion": "2022-09-01", "name": "[format('{0}/{1}/{2}', format('st{0}', variables('rgIdHash')), 'default', variables('storageFileShareName'))]", @@ -159,7 +164,7 @@ ] }, { - "condition": "[parameters('deployQdrant')]", + "condition": "[equals(parameters('memoryStore'), 'Qdrant')]", "type": "Microsoft.Storage/storageAccounts/fileServices", "apiVersion": "2022-09-01", "name": "[format('{0}/{1}', format('st{0}', variables('rgIdHash')), 'default')]", @@ -240,7 +245,10 @@ "properties": { "serverFarmId": "[resourceId('Microsoft.Web/serverfarms', format('asp-{0}-webapi', variables('uniqueName')))]", "httpsOnly": true, - "virtualNetworkSubnetId": "[reference(resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}', variables('uniqueName'))), '2021-05-01').subnets[0].id]" + "virtualNetworkSubnetId": "[reference(resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}', variables('uniqueName'))), '2021-05-01').subnets[0].id]", + "siteConfig": { + "healthCheckPath": "/healthz" + } }, "dependsOn": [ "[resourceId('Microsoft.Web/serverfarms', format('asp-{0}-webapi', variables('uniqueName')))]", @@ -252,7 +260,7 @@ "apiVersion": "2022-09-01", "name": "[format('{0}/{1}', format('app-{0}-webapi', variables('uniqueName')), 'web')]", "properties": { - "alwaysOn": true, + "alwaysOn": false, "cors": { "allowedOrigins": [ "http://localhost:3000", @@ -329,16 +337,28 @@ }, { "name": "MemoriesStore:Type", - "value": "[if(parameters('deployQdrant'), 'Qdrant', 'Volatile')]" + "value": "[parameters('memoryStore')]" }, { "name": "MemoriesStore:Qdrant:Host", - "value": "[if(parameters('deployQdrant'), format('https://{0}', reference(resourceId('Microsoft.Web/sites', format('app-{0}-qdrant', variables('uniqueName'))), '2022-09-01').defaultHostName), '')]" + "value": "[if(equals(parameters('memoryStore'), 'Qdrant'), format('https://{0}', reference(resourceId('Microsoft.Web/sites', format('app-{0}-qdrant', variables('uniqueName'))), '2022-09-01').defaultHostName), '')]" }, { "name": "MemoriesStore:Qdrant:Port", "value": "443" }, + { + "name": "MemoriesStore:AzureCognitiveSearch:UseVectorSearch", + "value": "true" + }, + { + "name": "MemoriesStore:AzureCognitiveSearch:Endpoint", + "value": "[if(equals(parameters('memoryStore'), 'AzureCognitiveSearch'), format('https://{0}.search.windows.net', format('acs-{0}', variables('uniqueName'))), '')]" + }, + { + "name": "MemoriesStore:AzureCognitiveSearch:Key", + "value": "[if(equals(parameters('memoryStore'), 'AzureCognitiveSearch'), listAdminKeys(resourceId('Microsoft.Search/searchServices', format('acs-{0}', variables('uniqueName'))), '2022-09-01').primaryKey, '')]" + }, { "name": "AzureSpeech:Region", "value": "[parameters('location')]" @@ -393,6 +413,7 @@ "[resourceId('Microsoft.Insights/components', format('appins-{0}', variables('uniqueName')))]", "[resourceId('Microsoft.Web/sites', format('app-{0}-qdrant', variables('uniqueName')))]", "[resourceId('Microsoft.Web/sites', format('app-{0}-webapi', variables('uniqueName')))]", + "[resourceId('Microsoft.Search/searchServices', format('acs-{0}', variables('uniqueName')))]", "[resourceId('Microsoft.DocumentDB/databaseAccounts', toLower(format('cosmos-{0}', variables('uniqueName'))))]", "[resourceId('Microsoft.CognitiveServices/accounts', format('ai-{0}', variables('uniqueName')))]", "[resourceId('Microsoft.CognitiveServices/accounts', format('cog-{0}', variables('uniqueName')))]" @@ -459,7 +480,7 @@ } }, { - "condition": "[parameters('deployQdrant')]", + "condition": "[equals(parameters('memoryStore'), 'Qdrant')]", "type": "Microsoft.Storage/storageAccounts", "apiVersion": "2022-09-01", "name": "[format('st{0}', variables('rgIdHash'))]", @@ -474,7 +495,7 @@ } }, { - "condition": "[parameters('deployQdrant')]", + "condition": "[equals(parameters('memoryStore'), 'Qdrant')]", "type": "Microsoft.Web/serverfarms", "apiVersion": "2022-03-01", "name": "[format('asp-{0}-qdrant', variables('uniqueName'))]", @@ -488,7 +509,7 @@ } }, { - "condition": "[parameters('deployQdrant')]", + "condition": "[equals(parameters('memoryStore'), 'Qdrant')]", "type": "Microsoft.Web/sites", "apiVersion": "2022-09-01", "name": "[format('app-{0}-qdrant', variables('uniqueName'))]", @@ -522,10 +543,10 @@ "azureStorageAccounts": { "aciqdrantshare": { "type": "AzureFiles", - "accountName": "[if(parameters('deployQdrant'), format('st{0}', variables('rgIdHash')), 'notdeployed')]", + "accountName": "[if(equals(parameters('memoryStore'), 'Qdrant'), format('st{0}', variables('rgIdHash')), 'notdeployed')]", "shareName": "[variables('storageFileShareName')]", "mountPath": "/qdrant/storage", - "accessKey": "[if(parameters('deployQdrant'), listKeys(resourceId('Microsoft.Storage/storageAccounts', format('st{0}', variables('rgIdHash'))), '2022-09-01').keys[0].value, '')]" + "accessKey": "[if(equals(parameters('memoryStore'), 'Qdrant'), listKeys(resourceId('Microsoft.Storage/storageAccounts', format('st{0}', variables('rgIdHash'))), '2022-09-01').keys[0].value, '')]" } } } @@ -536,6 +557,20 @@ "[resourceId('Microsoft.Network/virtualNetworks', format('vnet-{0}', variables('uniqueName')))]" ] }, + { + "condition": "[equals(parameters('memoryStore'), 'AzureCognitiveSearch')]", + "type": "Microsoft.Search/searchServices", + "apiVersion": "2022-09-01", + "name": "[format('acs-{0}', variables('uniqueName'))]", + "location": "[parameters('location')]", + "sku": { + "name": "basic" + }, + "properties": { + "replicaCount": 1, + "partitionCount": 1 + } + }, { "type": "Microsoft.Network/virtualNetworks", "apiVersion": "2021-05-01", @@ -655,7 +690,7 @@ ] }, { - "condition": "[parameters('deployQdrant')]", + "condition": "[equals(parameters('memoryStore'), 'Qdrant')]", "type": "Microsoft.Web/sites/virtualNetworkConnections", "apiVersion": "2022-09-01", "name": "[format('{0}/{1}', format('app-{0}-qdrant', variables('uniqueName')), 'qdrantSubnetConnection')]", From da16be294c577f74479b737a6df282c62bd17a0b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 23:17:49 +0000 Subject: [PATCH 014/582] Bump prettier from 2.8.8 to 3.0.0 in /webapp (#21) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bumps [prettier](https://github.com/prettier/prettier) from 2.8.8 to 3.0.0.
Release notes

Sourced from prettier's releases.

3.0.0

diff

🔗 Release note

3.0.0-alpha.6

What's Changed

Other changes since v2, see 3.0.0-alpha.1 release notes

Full Changelog: https://github.com/prettier/prettier/compare/3.0.0-alpha.5...3.0.0-alpha.6

3.0.0-alpha.5

What's Changed

Other changes since v2, see 3.0.0-alpha.1 release notes

Full Changelog: https://github.com/prettier/prettier/compare/3.0.0-alpha.4...3.0.0-alpha.5

3.0.0-alpha.4

What's Changed

Other changes since v2, see 3.0.0-alpha.1 release notes

Full Changelog: https://github.com/prettier/prettier/compare/3.0.0-alpha.3...3.0.0-alpha.4

3.0.0-alpha.3

  • Fix exports field in package.json file

Other changes since v2, see 3.0.0-alpha.1 release notes

Full Changelog: https://github.com/prettier/prettier/compare/3.0.0-alpha.2...3.0.0-alpha.3

3.0.0-alpha.2

  • Fix bundled index.cjs file

Other changes since v2, see 3.0.0-alpha.1 release notes

Full Changelog: https://github.com/prettier/prettier/compare/3.0.0-alpha.1...3.0.0-alpha.2

3.0.0-alpha.1

If you are a plugin developer, please try this version and send us feedback! Feel free to ping @​fisker if you have any questions about v3 migration.

... (truncated)

Changelog

Sourced from prettier's changelog.

3.0.0

diff

🔗 Release Notes

Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=prettier&package-manager=npm_and_yarn&previous-version=2.8.8&new-version=3.0.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- webapp/package.json | 2 +- webapp/yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 236115ca6..2abaddc02 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -44,7 +44,7 @@ "depcheck": "^1.4.3", "eslint": "^8.42.0", "http-server": "^14.1.1", - "prettier": "^2.8.1", + "prettier": "^3.0.0", "serve": "^14.2.0", "typescript": "5.1.6", "vsts-npm-auth": "^0.42.1", diff --git a/webapp/yarn.lock b/webapp/yarn.lock index fd89b9467..89c7ef017 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -9182,10 +9182,10 @@ prelude-ls@^1.2.1: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== -prettier@^2.8.1: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== +prettier@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.0.0.tgz#e7b19f691245a21d618c68bc54dc06122f6105ae" + integrity sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g== pretty-bytes@^5.3.0, pretty-bytes@^5.4.1: version "5.6.0" From 1ca2c5b4e46da47925418bbdf23d49eecddebbe6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 24 Jul 2023 23:18:10 +0000 Subject: [PATCH 015/582] Bump @types/node from 18.16.19 to 20.4.4 in /webapp (#23) Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 18.16.19 to 20.4.4.
Commits

[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=@types/node&package-manager=npm_and_yarn&previous-version=18.16.19&new-version=20.4.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`. [//]: # (dependabot-automerge-start) [//]: # (dependabot-automerge-end) ---
Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- webapp/package.json | 2 +- webapp/yarn.lock | 13 ++++--------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/webapp/package.json b/webapp/package.json index 2abaddc02..44dee43a8 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -37,7 +37,7 @@ "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@types/debug": "^4.1.7", - "@types/node": "^18.11.9", + "@types/node": "^20.4.4", "@types/react": "^18.0.28", "@types/react-dom": "^18.0.11", "better-vsts-npm-auth": "^7.0.0", diff --git a/webapp/yarn.lock b/webapp/yarn.lock index 89c7ef017..884657a8d 100644 --- a/webapp/yarn.lock +++ b/webapp/yarn.lock @@ -3076,15 +3076,10 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== -"@types/node@*": - version "20.4.2" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.2.tgz#129cc9ae69f93824f92fac653eebfb4812ab4af9" - integrity sha512-Dd0BYtWgnWJKwO1jkmTrzofjK2QXXcai0dmtzvIBhcA+RsG5h8R3xlyta0kGOZRNfL9GuRtb1knmPEhQrePCEw== - -"@types/node@^18.11.9": - version "18.16.19" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.16.19.tgz#cb03fca8910fdeb7595b755126a8a78144714eea" - integrity sha512-IXl7o+R9iti9eBW4Wg2hx1xQDig183jj7YLn8F7udNceyfkbn1ZxmzZXuak20gR40D7pIkIY1kYGx5VIGbaHKA== +"@types/node@*", "@types/node@^20.4.4": + version "20.4.4" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.4.4.tgz#c79c7cc22c9d0e97a7944954c9e663bcbd92b0cb" + integrity sha512-CukZhumInROvLq3+b5gLev+vgpsIqC2D0deQr/yS1WnxvmYLlJXZpaQrQiseMY+6xusl79E04UjWoqyr+t1/Ew== "@types/parse-json@^4.0.0": version "4.0.0" From 23097fff97c080c2a5c5ea4e251dfed938dd77e1 Mon Sep 17 00:00:00 2001 From: Desmond Howard Date: Tue, 25 Jul 2023 08:08:02 -0700 Subject: [PATCH 016/582] Add .prettierrc.js, .vscode/settings.json, and .vscode/extensions.json (#27) ### Motivation and Context these files allow for auto formatting and linting in VSCode as well as suggested extensions when a dev first opens the repo. ### Description copied from SK with the irrelevant configs removed. ### Contribution Checklist - [x] The code builds clean without any errors or warnings - [x] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone :smile: --- .vscode/extensions.json | 8 ++++ .vscode/settings.json | 60 ++++++++++++++++++++++++++++ .eslintrc.js => webapp/.eslintrc.cjs | 8 ++++ webapp/.prettierrc.cjs | 8 ++++ webapp/package.json | 2 +- 5 files changed, 85 insertions(+), 1 deletion(-) create mode 100644 .vscode/extensions.json create mode 100644 .vscode/settings.json rename .eslintrc.js => webapp/.eslintrc.cjs (84%) create mode 100644 webapp/.prettierrc.cjs diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..abd8d87a0 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,8 @@ +{ + "recommendations": [ + "ms-dotnettools.csharp", + "esbenp.prettier-vscode", + "dbaeumer.vscode-eslint", + "ms-semantic-kernel.semantic-kernel", + ] +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..7b4b9ac51 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,60 @@ +{ + "prettier.enable": true, + "editor.formatOnType": true, + "editor.formatOnSave": true, + "editor.formatOnPaste": true, + "[csharp]": { + "editor.defaultFormatter": "ms-dotnettools.csharp", + "editor.codeActionsOnSave": { + "source.fixAll": true + } + }, + "editor.bracketPairColorization.enabled": true, + "editor.guides.bracketPairs": "active", + "javascript.updateImportsOnFileMove.enabled": "always", + "search.exclude": { + "**/node_modules": true, + "**/build": true + }, + "[typescript]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.organizeImports": true, + "source.fixAll": true + } + }, + "[typescriptreact]": { + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.codeActionsOnSave": { + "source.organizeImports": true, + "source.fixAll": true + } + }, + "typescript.updateImportsOnFileMove.enabled": "always", + "eslint.enable": true, + "eslint.validate": [ + "javascript", + "javascriptreact", + "typescript", + "typescriptreact" + ], + "eslint.lintTask.enable": true, + "eslint.workingDirectories": [ + { + "mode": "auto" + } + ], + "eslint.options": { + "overrideConfigFile": "./package.json" + }, + "files.associations": { + "*.json": "jsonc" + }, + "files.exclude": { + "**/.git": true, + "**/.hg": true, + "**/CVS": true, + "**/.DS_Store": true, + "**/Thumbs.db": true + }, + } \ No newline at end of file diff --git a/.eslintrc.js b/webapp/.eslintrc.cjs similarity index 84% rename from .eslintrc.js rename to webapp/.eslintrc.cjs index 3755ebea6..8e6ebc201 100644 --- a/.eslintrc.js +++ b/webapp/.eslintrc.cjs @@ -25,6 +25,14 @@ module.exports = { '@typescript-eslint/consistent-type-imports': 'off', '@typescript-eslint/no-empty-function': 'off', '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], 'react/react-in-jsx-scope': 'off', 'react/prop-types': 'off', 'react/jsx-props-no-spreading': 'off', diff --git a/webapp/.prettierrc.cjs b/webapp/.prettierrc.cjs new file mode 100644 index 000000000..3ae5e9c4c --- /dev/null +++ b/webapp/.prettierrc.cjs @@ -0,0 +1,8 @@ +module.exports = { + bracketSpacing: true, + printWidth: 120, + singleQuote: true, + tabWidth: 4, + trailingComma: 'all', + useTabs: false, +}; diff --git a/webapp/package.json b/webapp/package.json index 44dee43a8..11a9a2f88 100644 --- a/webapp/package.json +++ b/webapp/package.json @@ -54,7 +54,7 @@ "extends": [ "react-app", "react-app/jest", - "../.eslintrc.js" + ".eslintrc.cjs" ] }, "browserslist": { From 0977441149d3f0057b8fc706e01970f1609396de Mon Sep 17 00:00:00 2001 From: Vic Perdana <7114832+vicperdana@users.noreply.github.com> Date: Wed, 26 Jul 2023 01:11:29 +1000 Subject: [PATCH 017/582] Minor update & fix to Azure Deployment docs and deploy-webapp.sh (#30) ### Motivation and Context ### Description The changes are minor and consisted of two items: - deploy/Readme.md: added a note to indicate that the step to deploy webapi is not needed as this is completed by previous step in Bicep deployment. - deploy/deploy-webapp.sh: fixed a minor error of if condition missing a space "-z" ### Contribution Checklist - [X] The code builds clean without any errors or warnings - [X] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations - [X] All unit tests pass, and I have added new tests where possible - [X] I didn't break anyone :smile: --- deploy/README.md | 2 ++ deploy/deploy-webapp.sh | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/deploy/README.md b/deploy/README.md index b58b25263..4ead863d2 100644 --- a/deploy/README.md +++ b/deploy/README.md @@ -51,6 +51,8 @@ You can also deploy the infrastructure directly from the Azure Portal by clickin # Deploy Backend (WebAPI) +> **_NOTE:_** This step can be skipped if the previous Azure Resources creation step succeeded without errors. The `deployWebApiPackage = true` setting in main.bicep ensures that the latest copilot chat api is deployed. + To deploy the backend, build the deployment package first and deploy it to the Azure resources created above. ## PowerShell diff --git a/deploy/deploy-webapp.sh b/deploy/deploy-webapp.sh index 2828f6872..77200321c 100755 --- a/deploy/deploy-webapp.sh +++ b/deploy/deploy-webapp.sh @@ -71,7 +71,7 @@ if [ $? -ne 0 ]; then az login --use-device-code fi -if [[-z "$AUTHORITY" ]]; then +if [[ -z "$AUTHORITY" ]]; then AUTHORITY="https://login.microsoftonline.com/common" fi From e343de29ca877e4588ac58e1ed2eb9f44fff14d1 Mon Sep 17 00:00:00 2001 From: Desmond Howard Date: Tue, 25 Jul 2023 08:13:23 -0700 Subject: [PATCH 018/582] Update labeler.yml (#28) - updates the Labeler action to auto-assign the "webapp", "webapi", "github actions", "documentation", and "deployment" labels. - also fixes broken "Development scripts" link in PR template --- .github/labeler.yml | 20 ++++++++++++++++++-- .github/pull_request_template.md | 2 +- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index c430e2da5..8cdb1b1be 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -1,3 +1,19 @@ -# Add 'documentation' label to any '.md' files +# Add 'webapp' label to any change within the 'webapp' directory +webapp: + - webapp/**/* + +# Add 'webapi' label to any change within the 'webapi' directory +webapi: + - webapi/**/* + +# Add 'deployment' label to any change within the 'deploy' directory +deployment: + - deploy/**/* + +# Add 'documentation' label to any change of '.md' files documentation: - - '**/*.md' \ No newline at end of file + - '**/*.md' + +# Add 'github actions' label to any change within the '.github/workflows' directory +'github actions': + - .github/workflows/**/* \ No newline at end of file diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index f5b95b7cf..743201eb4 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -18,6 +18,6 @@ Please help reviewers and future users, providing the following information: - [ ] The code builds clean without any errors or warnings -- [ ] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations +- [ ] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone :smile: From 6e9d24aa2e76f93e135e24e88f3e8a4ba50982fe Mon Sep 17 00:00:00 2001 From: Teresa Hoang <125500434+teresaqhoang@users.noreply.github.com> Date: Tue, 25 Jul 2023 15:35:13 -0700 Subject: [PATCH 019/582] =?UTF-8?q?=F0=9F=93=9D=20RLFH=20UX=20Skeleton=20(?= =?UTF-8?q?#31)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### Motivation and Context Added RLFH UI to demonstrate users can easily add this capability to their chatbot if they wanted. ### Description > This feature is for demonstration purposes only. We don't actually hook up to the server to store the human feedback or send it to the model. Details: - RLFH actions will only show on the most recent chat message in which the author is `bot`. - If user takes action, icon will be rendered to reflect action. - Data is only stored in frontend state. If app refreshes, all RLFH across all chats will be reset. Actions on chat message: ![image](https://github.com/microsoft/chat-copilot/assets/125500434/1b730018-ccf3-4356-a173-9c7d50c0cec8) Once user takes actions: ![image](https://github.com/microsoft/chat-copilot/assets/125500434/0d691a1a-970a-4847-98cb-c6f05e23941f) Future work - Add ability to turn of RLHF in settings dialog + add help link to docs there ### Contribution Checklist - [x] The code builds clean without any errors or warnings - [x] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#development-scripts) raises no violations ~~- [ ] All unit tests pass, and I have added new tests where possible~~ - [x] I didn't break anyone :smile: --- .../chat/chat-history/ChatHistoryItem.tsx | 17 ++++- .../chat/chat-history/UserFeedbackActions.tsx | 63 +++++++++++++++++++ webapp/src/components/shared/BundledIcons.tsx | 46 ++++++++++++++ webapp/src/libs/models/ChatMessage.ts | 12 ++++ webapp/src/redux/features/app/appSlice.ts | 2 +- .../conversations/conversationsSlice.ts | 18 +++++- webapp/src/styles.tsx | 4 +- 7 files changed, 156 insertions(+), 6 deletions(-) create mode 100644 webapp/src/components/chat/chat-history/UserFeedbackActions.tsx create mode 100644 webapp/src/components/shared/BundledIcons.tsx diff --git a/webapp/src/components/chat/chat-history/ChatHistoryItem.tsx b/webapp/src/components/chat/chat-history/ChatHistoryItem.tsx index d4e8d0ef6..b9a61bdd3 100644 --- a/webapp/src/components/chat/chat-history/ChatHistoryItem.tsx +++ b/webapp/src/components/chat/chat-history/ChatHistoryItem.tsx @@ -2,17 +2,19 @@ import { Persona, Text, makeStyles, mergeClasses, shorthands, tokens } from '@fluentui/react-components'; import React from 'react'; -import { AuthorRoles, ChatMessageType, IChatMessage } from '../../../libs/models/ChatMessage'; +import { AuthorRoles, ChatMessageType, IChatMessage, UserFeedback } from '../../../libs/models/ChatMessage'; import { GetResponseOptions, useChat } from '../../../libs/useChat'; import { useAppSelector } from '../../../redux/app/hooks'; import { RootState } from '../../../redux/app/store'; -import { Breakpoints } from '../../../styles'; +import { Breakpoints, customTokens } from '../../../styles'; import { timestampToDateString } from '../../utils/TextUtils'; import { PlanViewer } from '../plan-viewer/PlanViewer'; import { PromptDetails } from '../prompt-details/PromptDetails'; import { ChatHistoryDocumentContent } from './ChatHistoryDocumentContent'; import { ChatHistoryTextContent } from './ChatHistoryTextContent'; import * as utils from './../../utils/TextUtils'; +import { ThumbLike16Filled, ThumbDislike24Filled } from '@fluentui/react-icons'; +import { UserFeedbackActions } from './UserFeedbackActions'; const useClasses = makeStyles({ root: { @@ -23,6 +25,7 @@ const useClasses = makeStyles({ ...Breakpoints.small({ maxWidth: '100%', }), + ...shorthands.gap(customTokens.spacingHorizontalXS), }, debug: { position: 'absolute', @@ -91,6 +94,13 @@ export const ChatHistoryItem: React.FC = ({ message, getRe content = ; } + // TODO: hookup to backend + // Currently for demonstration purposes only, no feedback is actually sent to kernel / model + const showShowRLHFMessage = + message.userFeedback === UserFeedback.Requested && + messageIndex === conversations[selectedId].messages.length - 1 && + message.userId === 'bot'; + return (
= ({ message, getRe {isBot && }
{content} + {showShowRLHFMessage && } + {message.userFeedback === UserFeedback.Positive && } + {message.userFeedback === UserFeedback.Negative && } ); }; diff --git a/webapp/src/components/chat/chat-history/UserFeedbackActions.tsx b/webapp/src/components/chat/chat-history/UserFeedbackActions.tsx new file mode 100644 index 000000000..a766da776 --- /dev/null +++ b/webapp/src/components/chat/chat-history/UserFeedbackActions.tsx @@ -0,0 +1,63 @@ +import { Button, Text, Tooltip, makeStyles } from '@fluentui/react-components'; +import { useCallback } from 'react'; +import { UserFeedback } from '../../../libs/models/ChatMessage'; +import { useAppDispatch, useAppSelector } from '../../../redux/app/hooks'; +import { RootState } from '../../../redux/app/store'; +import { setUserFeedback } from '../../../redux/features/conversations/conversationsSlice'; +import { ThumbDislike16, ThumbLike16 } from '../../shared/BundledIcons'; + +const useClasses = makeStyles({ + root: { + display: 'flex', + 'place-content': 'flex-end', + alignItems: 'center', + }, +}); + +interface IUserFeedbackProps { + messageIndex: number; +} + +export const UserFeedbackActions: React.FC = ({ messageIndex }) => { + const classes = useClasses(); + + const dispatch = useAppDispatch(); + const { selectedId } = useAppSelector((state: RootState) => state.conversations); + + const onUserFeedbackProvided = useCallback( + (positive: boolean) => { + dispatch( + setUserFeedback({ + userFeedback: positive ? UserFeedback.Positive : UserFeedback.Negative, + messageIndex, + chatId: selectedId, + }), + ); + }, + [dispatch, messageIndex, selectedId], + ); + + return ( +
+ + AI-generated content may be incorrect + + +
+ ); +}; diff --git a/webapp/src/components/shared/BundledIcons.tsx b/webapp/src/components/shared/BundledIcons.tsx new file mode 100644 index 000000000..b18dd355c --- /dev/null +++ b/webapp/src/components/shared/BundledIcons.tsx @@ -0,0 +1,46 @@ +import { + Add20Filled, + Add20Regular, + AppsAddIn24Filled, + AppsAddIn24Regular, + ArrowDownload16Filled, + ArrowDownload16Regular, + BotAdd20Filled, + BotAdd20Regular, + Checkmark20Filled, + Checkmark20Regular, + Delete16Filled, + Delete16Regular, + Dismiss16Filled, + Dismiss16Regular, + Dismiss20Filled, + Dismiss20Regular, + EditFilled, + EditRegular, + Filter20Filled, + Filter20Regular, + Info16Filled, + Info16Regular, + Share20Filled, + Share20Regular, + ThumbDislike16Filled, + ThumbDislike16Regular, + ThumbLike16Filled, + ThumbLike16Regular, + bundleIcon, +} from '@fluentui/react-icons'; + +export const Add20 = bundleIcon(Add20Filled, Add20Regular); +export const AppsAddIn24 = bundleIcon(AppsAddIn24Filled, AppsAddIn24Regular); +export const BotAdd20 = bundleIcon(BotAdd20Filled, BotAdd20Regular); +export const Checkmark20 = bundleIcon(Checkmark20Filled, Checkmark20Regular); +export const Delete16 = bundleIcon(Delete16Filled, Delete16Regular); +export const Dismiss16 = bundleIcon(Dismiss16Filled, Dismiss16Regular); +export const Dismiss20 = bundleIcon(Dismiss20Filled, Dismiss20Regular); +export const Filter20 = bundleIcon(Filter20Filled, Filter20Regular); +export const Edit = bundleIcon(EditFilled, EditRegular); +export const ArrowDownload16 = bundleIcon(ArrowDownload16Filled, ArrowDownload16Regular); +export const Share20 = bundleIcon(Share20Filled, Share20Regular); +export const Info16 = bundleIcon(Info16Filled, Info16Regular); +export const ThumbLike16 = bundleIcon(ThumbLike16Filled, ThumbLike16Regular); +export const ThumbDislike16 = bundleIcon(ThumbDislike16Filled, ThumbDislike16Regular); diff --git a/webapp/src/libs/models/ChatMessage.ts b/webapp/src/libs/models/ChatMessage.ts index fc33cf06a..8bc3a0c90 100644 --- a/webapp/src/libs/models/ChatMessage.ts +++ b/webapp/src/libs/models/ChatMessage.ts @@ -30,6 +30,16 @@ export enum ChatMessageType { Document, } +/** + * States for RLHF + */ +export enum UserFeedback { + Unknown, + Requested, + Positive, + Negative, +} + export interface IChatMessage { type: ChatMessageType; timestamp: number; @@ -41,4 +51,6 @@ export interface IChatMessage { authorRole: AuthorRoles; debug?: string; state?: PlanState; + // TODO: Persistent RLHF, view only right now + userFeedback?: UserFeedback; } diff --git a/webapp/src/redux/features/app/appSlice.ts b/webapp/src/redux/features/app/appSlice.ts index 485c11f2d..50f95d356 100644 --- a/webapp/src/redux/features/app/appSlice.ts +++ b/webapp/src/redux/features/app/appSlice.ts @@ -8,7 +8,7 @@ const initialState: AppState = { alerts: [ { message: - 'Copilot chat is designed for internal use only. By using this chat bot, you agree to not to share confidential or customer information or store sensitive information in chat history. Further, you agree that Copilot chat can collect and retain your chat history for service improvement.', + 'By using Chat Copilot, you agree to protect sensitive data, not store it in chat, and allow chat history collection for service improvements. This tool is for internal use only.', type: AlertType.Info, }, ], diff --git a/webapp/src/redux/features/conversations/conversationsSlice.ts b/webapp/src/redux/features/conversations/conversationsSlice.ts index 1f929e3a9..b06ec2110 100644 --- a/webapp/src/redux/features/conversations/conversationsSlice.ts +++ b/webapp/src/redux/features/conversations/conversationsSlice.ts @@ -1,7 +1,7 @@ // Copyright (c) Microsoft. All rights reserved. import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'; -import { IChatMessage } from '../../../libs/models/ChatMessage'; +import { ChatMessageType, IChatMessage, UserFeedback } from '../../../libs/models/ChatMessage'; import { IChatUser } from '../../../libs/models/ChatUser'; import { PlanState } from '../../../libs/models/Plan'; import { ChatState } from './ChatState'; @@ -112,6 +112,15 @@ export const conversationsSlice: Slice = createSlice({ const conversation = state.conversations[chatId]; conversation.botResponseStatus = status; }, + setUserFeedback: ( + state: ConversationsState, + action: PayloadAction<{ userFeedback: UserFeedback; messageIndex: number; chatId?: string }>, + ) => { + const { userFeedback, messageIndex, chatId } = action.payload; + const id = chatId ?? state.selectedId; + state.conversations[id].messages[messageIndex].userFeedback = userFeedback; + frontLoadChat(state, id); + }, }, }); @@ -128,6 +137,7 @@ export const { updateUserIsTypingFromServer, updateBotResponseStatusFromServer, setUsersLoaded, + setUserFeedback, } = conversationsSlice.actions; export default conversationsSlice.reducer; @@ -139,7 +149,11 @@ const frontLoadChat = (state: ConversationsState, id: string) => { }; const updateConversation = (state: ConversationsState, chatId: string, message: IChatMessage) => { - state.conversations[chatId].messages.push(message); + const requestUserFeedback = message.userId === 'bot' && message.type === ChatMessageType.Message; + state.conversations[chatId].messages.push({ + ...message, + userFeedback: requestUserFeedback ? UserFeedback.Requested : undefined, + }); frontLoadChat(state, chatId); }; diff --git a/webapp/src/styles.tsx b/webapp/src/styles.tsx index 1baabe267..e581b079b 100644 --- a/webapp/src/styles.tsx +++ b/webapp/src/styles.tsx @@ -1,4 +1,4 @@ -import { BrandVariants, GriffelStyle, createLightTheme, tokens } from '@fluentui/react-components'; +import { BrandVariants, GriffelStyle, createLightTheme, themeToTokensObject, tokens } from '@fluentui/react-components'; const semanticKernelBrandRamp: BrandVariants = { 10: '#060103', @@ -21,6 +21,8 @@ const semanticKernelBrandRamp: BrandVariants = { export const semanticKernelLightTheme = createLightTheme(semanticKernelBrandRamp); +export const customTokens = themeToTokensObject(semanticKernelLightTheme); + export const Breakpoints = { small: (style: GriffelStyle): Record => { return { '@media (max-width: 744px)': style }; From 4fdde0bbf114ceaaef5f0164472273db1cd1449d Mon Sep 17 00:00:00 2001 From: Desmond Howard Date: Tue, 25 Jul 2023 16:27:03 -0700 Subject: [PATCH 020/582] Add support for chat streaming (#18) ### Motivation and Context responses will now be streamed directly from the Kernel to all users in the chat. ### Description - `ChatSkill.cs`: - added `StreamResponseToClient()` to broadcast the streamed response to all clients. - changed `GetChatResponseAsync()` to use `Task.WhenAll` when extracting audience/user intent and semantic/document memories. - changed `GetChatContextTokenLimit()` to account for the tokens used in extracting the audience ### Preview **regular messages:** ![gif](https://github.com/microsoft/chat-copilot/assets/52973358/b5ba0b1f-3ddc-4648-8eff-587735770b7a) **planner messages:** ![gif2](https://github.com/microsoft/chat-copilot/assets/52973358/79bfa394-7857-4e06-9302-174a4e6d1247) **multiuser messages:** ![gif](https://github.com/microsoft/chat-copilot/assets/52973358/8013ce33-3eff-4bc2-bf74-dafac378e9b0) ### Contribution Checklist - [x] The code builds clean without any errors or warnings - [x] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations - [x] All unit tests pass, and I have added new tests where possible - [x] I didn't break anyone :smile: --- .../CopilotChat/Controllers/ChatController.cs | 2 - .../Controllers/DocumentImportController.cs | 4 +- webapi/CopilotChat/Hubs/MessageRelayHub.cs | 11 +- .../Skills/ChatSkills/ChatSkill.cs | 256 +++++++++++------- webapp/src/components/chat/ChatInput.tsx | 7 +- webapp/src/components/chat/ChatRoom.tsx | 19 +- .../chat/chat-history/UserFeedbackActions.tsx | 10 +- .../chat/plan-viewer/PlanViewer.tsx | 12 +- webapp/src/libs/models/ChatMessage.ts | 2 +- webapp/src/libs/services/ChatService.ts | 5 +- .../conversations/conversationsSlice.ts | 87 +++--- .../message-relay/signalRMiddleware.ts | 69 +++-- 12 files changed, 268 insertions(+), 216 deletions(-) diff --git a/webapi/CopilotChat/Controllers/ChatController.cs b/webapi/CopilotChat/Controllers/ChatController.cs index b79a907b7..bf9824b67 100644 --- a/webapi/CopilotChat/Controllers/ChatController.cs +++ b/webapi/CopilotChat/Controllers/ChatController.cs @@ -41,7 +41,6 @@ public class ChatController : ControllerBase, IDisposable private readonly ITelemetryService _telemetryService; private const string ChatSkillName = "ChatSkill"; private const string ChatFunctionName = "Chat"; - private const string ReceiveResponseClientCall = "ReceiveResponse"; private const string GeneratingResponseClientCall = "ReceiveBotResponseStatus"; public ChatController(ILogger logger, ITelemetryService telemetryService) @@ -130,7 +129,6 @@ public async Task ChatAsync( if (ask.Variables.Where(v => v.Key == "chatId").Any()) { var chatId = ask.Variables.Where(v => v.Key == "chatId").First().Value; - await messageRelayHubContext.Clients.Group(chatId).SendAsync(ReceiveResponseClientCall, chatSkillAskResult, chatId); await messageRelayHubContext.Clients.Group(chatId).SendAsync(GeneratingResponseClientCall, chatId, null); } diff --git a/webapi/CopilotChat/Controllers/DocumentImportController.cs b/webapi/CopilotChat/Controllers/DocumentImportController.cs index d53020553..f663662fa 100644 --- a/webapi/CopilotChat/Controllers/DocumentImportController.cs +++ b/webapi/CopilotChat/Controllers/DocumentImportController.cs @@ -70,7 +70,7 @@ private enum SupportedFileType private readonly ChatMessageRepository _messageRepository; private readonly ChatParticipantRepository _participantRepository; private const string GlobalDocumentUploadedClientCall = "GlobalDocumentUploaded"; - private const string ChatDocumentUploadedClientCall = "ChatDocumentUploaded"; + private const string ReceiveMessageClientCall = "ReceiveMessage"; private readonly ITesseractEngine _tesseractEngine; /// @@ -148,7 +148,7 @@ public async Task ImportDocumentsAsync( var chatId = documentImportForm.ChatId.ToString(); await messageRelayHubContext.Clients.Group(chatId) - .SendAsync(ChatDocumentUploadedClientCall, chatMessage, chatId); + .SendAsync(ReceiveMessageClientCall, chatMessage, chatId); return this.Ok(chatMessage); } diff --git a/webapi/CopilotChat/Hubs/MessageRelayHub.cs b/webapi/CopilotChat/Hubs/MessageRelayHub.cs index ec6249071..a00f97da5 100644 --- a/webapi/CopilotChat/Hubs/MessageRelayHub.cs +++ b/webapi/CopilotChat/Hubs/MessageRelayHub.cs @@ -30,7 +30,7 @@ public MessageRelayHub(ILogger logger) /// TODO: Retrieve the user ID from the claims and call this method /// from the OnConnectedAsync method instead of the frontend. /// - /// The ChatID used as group id for SignalR. + /// The chat ID used as group id for SignalR. public async Task AddClientToGroupAsync(string chatId) { await this.Groups.AddToGroupAsync(this.Context.ConnectionId, chatId); @@ -39,17 +39,18 @@ public async Task AddClientToGroupAsync(string chatId) /// /// Sends a message to all users except the sender. /// - /// The ChatID used as group id for SignalR. + /// The chat ID used as group id for SignalR. + /// The user ID of the user that sent the message. /// The message to send. - public async Task SendMessageAsync(string chatId, object message) + public async Task SendMessageAsync(string chatId, string senderId, object message) { - await this.Clients.OthersInGroup(chatId).SendAsync(ReceiveMessageClientCall, message, chatId); + await this.Clients.OthersInGroup(chatId).SendAsync(ReceiveMessageClientCall, chatId, senderId, message); } /// /// Sends the typing state to all users except the sender. /// - /// The ChatID used as group id for SignalR. + /// The chat ID used as group id for SignalR. /// The user ID of the user who is typing. /// Whether the user is typing. /// A task that represents the asynchronous operation. diff --git a/webapi/CopilotChat/Skills/ChatSkills/ChatSkill.cs b/webapi/CopilotChat/Skills/ChatSkills/ChatSkill.cs index c414b6690..2f6d37749 100644 --- a/webapi/CopilotChat/Skills/ChatSkills/ChatSkill.cs +++ b/webapi/CopilotChat/Skills/ChatSkills/ChatSkill.cs @@ -12,7 +12,9 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Microsoft.SemanticKernel; +using Microsoft.SemanticKernel.AI.ChatCompletion; using Microsoft.SemanticKernel.AI.TextCompletion; +using Microsoft.SemanticKernel.Diagnostics; using Microsoft.SemanticKernel.Orchestration; using Microsoft.SemanticKernel.SkillDefinition; using Microsoft.SemanticKernel.TemplateEngine; @@ -258,7 +260,7 @@ public async Task ChatAsync( SKContext context) { // Save this new message to memory such that subsequent chat responses can use it - await this.UpdateResponseStatusOnClient(chatId, "Saving user message to chat history"); + await this.UpdateBotResponseStatusOnClient(chatId, "Saving user message to chat history"); await this.SaveNewMessageAsync(message, userId, userName, chatId, messageType); // Clone the context to avoid modifying the original context variables. @@ -271,40 +273,24 @@ public async Task ChatAsync( if (!string.IsNullOrWhiteSpace(planJson) && !string.IsNullOrEmpty(messageId)) { - await this.UpdateResponseAsync(planJson, messageId); + await this.UpdateChatMessageContentAsync(planJson, messageId); } - var response = chatContext.Variables.ContainsKey("userCancelledPlan") - ? "I am sorry the plan did not meet your goals." - : await this.GetChatResponseAsync(chatId, chatContext); + // Save hardcoded response if user cancelled plan + if (chatContext.Variables.ContainsKey("userCancelledPlan")) + { + await this.SaveNewResponseAsync("I am sorry the plan did not meet your goals.", string.Empty, chatId, userId); + return context; + } - if (chatContext.ErrorOccurred) + // Get the chat response + var chatMessage = await this.GetChatResponseAsync(chatId, userId, chatContext); + if (chatMessage == null) { context.Fail(chatContext.LastErrorDescription); return context; } - // Retrieve the prompt used to generate the response - // and return it to the caller via the context variables. - chatContext.Variables.TryGetValue("prompt", out string? prompt); - prompt ??= string.Empty; - context.Variables.Set("prompt", prompt); - - // Save this response to memory such that subsequent chat responses can use it - await this.UpdateResponseStatusOnClient(chatId, "Saving bot message to chat history"); - ChatMessage botMessage = await this.SaveNewResponseAsync(response, prompt, chatId); - context.Variables.Set("messageId", botMessage.Id); - context.Variables.Set("messageType", ((int)botMessage.Type).ToString(CultureInfo.InvariantCulture)); - - // Extract semantic chat memory - await this.UpdateResponseStatusOnClient(chatId, "Extracting semantic chat memory"); - await SemanticChatMemoryExtractor.ExtractSemanticChatMemoryAsync( - chatId, - this._kernel, - chatContext, - this._promptOptions); - - context.Variables.Update(response); return context; } @@ -313,109 +299,123 @@ await SemanticChatMemoryExtractor.ExtractSemanticChatMemoryAsync( /// /// Generate the necessary chat context to create a prompt then invoke the model to get a response. /// + /// The chat ID + /// The user ID /// The SKContext. - /// A response from the model. - private async Task GetChatResponseAsync(string chatId, SKContext chatContext) + /// The created chat message containing the model-generated response. + private async Task GetChatResponseAsync(string chatId, string userId, SKContext chatContext) { - // 0. Get the audience - await this.UpdateResponseStatusOnClient(chatId, "Extracting audience"); + // Get the audience + await this.UpdateBotResponseStatusOnClient(chatId, "Extracting audience"); var audience = await this.GetAudienceAsync(chatContext); if (chatContext.ErrorOccurred) { - return string.Empty; + return null; } - // 1. Extract user intent from the conversation history. - await this.UpdateResponseStatusOnClient(chatId, "Extracting user intent"); + // Extract user intent from the conversation history. + await this.UpdateBotResponseStatusOnClient(chatId, "Extracting user intent"); var userIntent = await this.GetUserIntentAsync(chatContext); if (chatContext.ErrorOccurred) { - return string.Empty; + return null; } - // 2. Calculate the remaining token budget. - await this.UpdateResponseStatusOnClient(chatId, "Calculating remaining token budget"); - var remainingToken = this.GetChatContextTokenLimit(userIntent); + chatContext.Variables.Set("audience", audience); + chatContext.Variables.Set("userIntent", userIntent); + + // Calculate the remaining token budget. + await this.UpdateBotResponseStatusOnClient(chatId, "Calculating remaining token budget"); + var remainingToken = this.GetChatContextTokenLimit(audience, userIntent); - // 3. Acquire external information from planner - await this.UpdateResponseStatusOnClient(chatId, "Acquiring external information from planner"); + // Acquire external information from planner + await this.UpdateBotResponseStatusOnClient(chatId, "Acquiring external information from planner"); var externalInformationTokenLimit = (int)(remainingToken * this._promptOptions.ExternalInformationContextWeight); var planResult = await this.AcquireExternalInformationAsync(chatContext, userIntent, externalInformationTokenLimit); if (chatContext.ErrorOccurred) { - return string.Empty; + return null; } // If plan is suggested, send back to user for approval before running - if (this._externalInformationSkill.ProposedPlan != null) + var proposedPlan = this._externalInformationSkill.ProposedPlan; + if (proposedPlan != null) { - chatContext.Variables.Set("prompt", this._externalInformationSkill.ProposedPlan.Plan.Description); - return JsonSerializer.Serialize(this._externalInformationSkill.ProposedPlan); + var prompt = proposedPlan.Plan.Description; + chatContext.Variables.Set("prompt", prompt); + + // Save a new response to the chat history with the proposed plan content + return await this.SaveNewResponseAsync(JsonSerializer.Serialize(proposedPlan), prompt, chatId, userId); } - // 4. Query relevant semantic memories - await this.UpdateResponseStatusOnClient(chatId, "Querying semantic memories"); + // Query relevant semantic and document memories + await this.UpdateBotResponseStatusOnClient(chatId, "Extracting semantic and document memories"); var chatMemoriesTokenLimit = (int)(remainingToken * this._promptOptions.MemoriesResponseContextWeight); - var chatMemories = await this._semanticChatMemorySkill.QueryMemoriesAsync(userIntent, chatId, chatMemoriesTokenLimit, chatContext.Memory); - if (chatContext.ErrorOccurred) + var documentContextTokenLimit = (int)(remainingToken * this._promptOptions.DocumentContextWeight); + string[] tasks; + try { - return string.Empty; + tasks = await Task.WhenAll( + this._semanticChatMemorySkill.QueryMemoriesAsync(userIntent, chatId, chatMemoriesTokenLimit, chatContext.Memory), + this._documentMemorySkill.QueryDocumentsAsync(userIntent, chatId, documentContextTokenLimit, chatContext.Memory) + ); } - - // 5. Query relevant document memories - await this.UpdateResponseStatusOnClient(chatId, "Querying document memories"); - var documentContextTokenLimit = (int)(remainingToken * this._promptOptions.DocumentContextWeight); - var documentMemories = await this._documentMemorySkill.QueryDocumentsAsync(userIntent, chatId, documentContextTokenLimit, chatContext.Memory); - if (chatContext.ErrorOccurred) + catch (SKException ex) { - return string.Empty; + chatContext.Fail(ex.Message, ex); + return null; } + var chatMemories = tasks[0]; + var documentMemories = tasks[1]; - // 6. Fill in the chat history if there is any token budget left + // Fill in the chat history if there is any token budget left var chatContextComponents = new List() { chatMemories, documentMemories, planResult }; var chatContextText = string.Join("\n\n", chatContextComponents.Where(c => !string.IsNullOrEmpty(c))); - var chatContextTextTokenCount = remainingToken - Utilities.TokenCount(chatContextText); - if (chatContextTextTokenCount > 0) + var chatHistoryTokenLimit = remainingToken - Utilities.TokenCount(chatContextText); + if (chatHistoryTokenLimit > 0) { - await this.UpdateResponseStatusOnClient(chatId, "Extracting chat history"); - var chatHistory = await this.ExtractChatHistoryAsync(chatId, chatContextTextTokenCount); + await this.UpdateBotResponseStatusOnClient(chatId, "Extracting chat history"); + var chatHistory = await this.ExtractChatHistoryAsync(chatId, chatHistoryTokenLimit); if (chatContext.ErrorOccurred) { - return string.Empty; + return null; } chatContextText = $"{chatContextText}\n{chatHistory}"; } - // Invoke the model + // Set variables needed in prompt chatContext.Variables.Set("audience", audience); - chatContext.Variables.Set("UserIntent", userIntent); - chatContext.Variables.Set("ChatContext", chatContextText); + chatContext.Variables.Set("userIntent", userIntent); + chatContext.Variables.Set("chatContext", chatContextText); + // Render the prompt var promptRenderer = new PromptTemplateEngine(); var renderedPrompt = await promptRenderer.RenderAsync( this._promptOptions.SystemChatPrompt, chatContext); - - var completionFunction = this._kernel.CreateSemanticFunction( - renderedPrompt, - skillName: nameof(ChatSkill), - description: "Complete the prompt."); - - await this.UpdateResponseStatusOnClient(chatId, "Invoking the AI model"); - chatContext = await completionFunction.InvokeAsync( - context: chatContext, - settings: this.CreateChatResponseCompletionSettings() - ); - - // Allow the caller to view the prompt used to generate the response chatContext.Variables.Set("prompt", renderedPrompt); if (chatContext.ErrorOccurred) { - return string.Empty; + return null; } - return chatContext.Result; + // Stream the response to the client + await this.UpdateBotResponseStatusOnClient(chatId, "Generating bot response"); + var chatMessage = await this.StreamResponseToClient(chatId, userId, renderedPrompt); + + // Extract semantic chat memory + await this.UpdateBotResponseStatusOnClient(chatId, "Generating semantic chat memory"); + await SemanticChatMemoryExtractor.ExtractSemanticChatMemoryAsync( + chatId, + this._kernel, + chatContext, + this._promptOptions); + + // Save the message + await this.UpdateBotResponseStatusOnClient(chatId, "Saving message to chat history"); + await this._chatMessageRepository.UpsertAsync(chatMessage); + return chatMessage; } /// @@ -482,6 +482,10 @@ private async Task GetUserIntentAsync(SKContext context) /// Helper function create the correct context variables to /// query chat memories from the chat memory store. /// + /// The chat memories. + /// The SKContext. + /// The user intent. + /// Maximum number of tokens. private Task QueryChatMemoriesAsync(SKContext context, string userIntent, int tokenLimit) { return this._semanticChatMemorySkill.QueryMemoriesAsync(userIntent, context["chatId"], tokenLimit, context.Memory); @@ -491,6 +495,10 @@ private Task QueryChatMemoriesAsync(SKContext context, string userIntent /// Helper function create the correct context variables to /// query document memories from the document memory store. /// + /// The document memories. + /// The SKContext. + /// The user intent. + /// Maximum number of tokens. private Task QueryDocumentsAsync(SKContext context, string userIntent, int tokenLimit) { return this._documentMemorySkill.QueryDocumentsAsync(userIntent, context["chatId"], tokenLimit, context.Memory); @@ -499,6 +507,10 @@ private Task QueryDocumentsAsync(SKContext context, string userIntent, i /// /// Helper function create the correct context variables to acquire external information. /// + /// The plan. + /// The SKContext. + /// The user intent. + /// Maximum number of tokens. private async Task AcquireExternalInformationAsync(SKContext context, string userIntent, int tokenLimit) { var contextVariables = context.Variables.Clone(); @@ -561,8 +573,9 @@ private async Task SaveNewMessageAsync(string message, string userI /// Response from the chat. /// Prompt used to generate the response. /// The chat ID + /// The user ID /// The created chat message. - private async Task SaveNewResponseAsync(string response, string prompt, string chatId) + private async Task SaveNewResponseAsync(string response, string prompt, string chatId, string userId) { // Make sure the chat exists. if (!await this._chatSessionRepository.TryFindByIdAsync(chatId, v => _ = v)) @@ -570,9 +583,9 @@ private async Task SaveNewResponseAsync(string response, string pro throw new ArgumentException("Chat session does not exist."); } - var chatMessage = ChatMessage.CreateBotResponseMessage(chatId, response, prompt); - await this._chatMessageRepository.CreateAsync(chatMessage); - + // Save message to chat history + var chatMessage = await this.CreateBotMessageOnClient(chatId, userId, prompt, response); + await this._chatMessageRepository.UpsertAsync(chatMessage); return chatMessage; } @@ -581,7 +594,7 @@ private async Task SaveNewResponseAsync(string response, string pro /// /// Updated response from the chat. /// The chat message ID - private async Task UpdateResponseAsync(string updatedResponse, string messageId) + private async Task UpdateChatMessageContentAsync(string updatedResponse, string messageId) { // Make sure the chat exists. var chatMessage = await this._chatMessageRepository.FindByIdAsync(messageId); @@ -591,11 +604,11 @@ private async Task UpdateResponseAsync(string updatedResponse, string messageId) } /// - /// Create a completion settings object for chat response. Parameters are read from the PromptSettings class. + /// Create `ChatRequestSettings` for chat response. Parameters are read from the PromptSettings class. /// - private CompleteRequestSettings CreateChatResponseCompletionSettings() + private ChatRequestSettings CreateChatRequestSettings() { - var completionSettings = new CompleteRequestSettings + return new ChatRequestSettings { MaxTokens = this._promptOptions.ResponseTokenLimit, Temperature = this._promptOptions.ResponseTemperature, @@ -603,16 +616,14 @@ private CompleteRequestSettings CreateChatResponseCompletionSettings() FrequencyPenalty = this._promptOptions.ResponseFrequencyPenalty, PresencePenalty = this._promptOptions.ResponsePresencePenalty }; - - return completionSettings; } /// - /// Create a completion settings object for intent response. Parameters are read from the PromptSettings class. + /// Create `CompleteRequestSettings` for intent response. Parameters are read from the PromptSettings class. /// private CompleteRequestSettings CreateIntentCompletionSettings() { - var completionSettings = new CompleteRequestSettings + return new CompleteRequestSettings { MaxTokens = this._promptOptions.ResponseTokenLimit, Temperature = this._promptOptions.IntentTemperature, @@ -621,21 +632,21 @@ private CompleteRequestSettings CreateIntentCompletionSettings() PresencePenalty = this._promptOptions.IntentPresencePenalty, StopSequences = new string[] { "] bot:" } }; - - return completionSettings; } /// /// Calculate the remaining token budget for the chat response prompt. /// This is the token limit minus the token count of the user intent and the system commands. /// + /// The audience returned by the model. /// The user intent returned by the model. /// The remaining token limit. - private int GetChatContextTokenLimit(string userIntent) + private int GetChatContextTokenLimit(string audience, string userIntent) { var tokenLimit = this._promptOptions.CompletionTokenLimit; var remainingToken = tokenLimit - + Utilities.TokenCount(audience) - Utilities.TokenCount(userIntent) - this._promptOptions.ResponseTokenLimit - Utilities.TokenCount(string.Join("\n", new string[] @@ -649,12 +660,63 @@ private int GetChatContextTokenLimit(string userIntent) return remainingToken; } + /// + /// Stream the response to the client. + /// + /// The chat ID + /// The user ID + /// Prompt used to generate the response + /// The created chat message + private async Task StreamResponseToClient(string chatId, string userId, string prompt) + { + // Create the stream + var chatCompletion = this._kernel.GetService(); + var stream = chatCompletion.GenerateMessageStreamAsync(chatCompletion.CreateNewChat(prompt), this.CreateChatRequestSettings()); + + // Create message on client + var chatMessage = await this.CreateBotMessageOnClient(chatId, userId, prompt, string.Empty); + + // Stream the message to the client + await foreach (string contentPiece in stream) + { + chatMessage.Content += contentPiece; + await this.UpdateMessageContentOnClient(chatId, chatMessage); + } + + return chatMessage; + } + + /// + /// Create an empty message on the client to begin the response. + /// + /// The chat ID + /// The user ID + /// Prompt used to generate the message + /// Content of the message + /// The created chat message + private async Task CreateBotMessageOnClient(string chatId, string userId, string prompt, string content) + { + var chatMessage = ChatMessage.CreateBotResponseMessage(chatId, content, prompt); + await this._messageRelayHubContext.Clients.Group(chatId).SendAsync("ReceiveMessage", chatId, userId, chatMessage); + return chatMessage; + } + + /// + /// Update the response on the client. + /// + /// The chat ID + /// The message + private async Task UpdateMessageContentOnClient(string chatId, ChatMessage message) + { + await this._messageRelayHubContext.Clients.Group(chatId).SendAsync("ReceiveMessageStream", chatId, message.Id, message.Content); + } + /// /// Update the status of the response on the client. /// - /// Id of the chat session + /// The chat ID /// Current status of the response - private async Task UpdateResponseStatusOnClient(string chatId, string status) + private async Task UpdateBotResponseStatusOnClient(string chatId, string status) { await this._messageRelayHubContext.Clients.Group(chatId).SendAsync("ReceiveBotResponseStatus", chatId, status); } diff --git a/webapp/src/components/chat/ChatInput.tsx b/webapp/src/components/chat/ChatInput.tsx index e3d4566ae..55a1c191e 100644 --- a/webapp/src/components/chat/ChatInput.tsx +++ b/webapp/src/components/chat/ChatInput.tsx @@ -14,10 +14,7 @@ import { GetResponseOptions, useChat } from '../../libs/useChat'; import { useAppDispatch, useAppSelector } from '../../redux/app/hooks'; import { RootState } from '../../redux/app/store'; import { addAlert } from '../../redux/features/app/appSlice'; -import { - editConversationInput, - updateBotResponseStatusFromServer, -} from '../../redux/features/conversations/conversationsSlice'; +import { editConversationInput, updateBotResponseStatus } from '../../redux/features/conversations/conversationsSlice'; import { SpeechService } from './../../libs/services/SpeechService'; import { updateUserIsTyping } from './../../redux/features/conversations/conversationsSlice'; import { ChatStatus } from './ChatStatus'; @@ -153,7 +150,7 @@ export const ChatInput: React.FC = ({ isDraggingOver, onDragLeav setValue(''); dispatch(editConversationInput({ id: selectedId, newInput: '' })); - dispatch(updateBotResponseStatusFromServer({ chatId: selectedId, status: 'Calling the kernel' })); + dispatch(updateBotResponseStatus({ chatId: selectedId, status: 'Calling the kernel' })); onSubmit({ value, messageType, chatId: selectedId }).catch((error) => { const message = `Error submitting chat input: ${(error as Error).message}`; log(message); diff --git a/webapp/src/components/chat/ChatRoom.tsx b/webapp/src/components/chat/ChatRoom.tsx index 6ae524d39..6645a6a94 100644 --- a/webapp/src/components/chat/ChatRoom.tsx +++ b/webapp/src/components/chat/ChatRoom.tsx @@ -8,7 +8,7 @@ import { AuthorRoles, IChatMessage } from '../../libs/models/ChatMessage'; import { GetResponseOptions, useChat } from '../../libs/useChat'; import { useAppDispatch, useAppSelector } from '../../redux/app/hooks'; import { RootState } from '../../redux/app/store'; -import { updateConversationFromUser } from '../../redux/features/conversations/conversationsSlice'; +import { addMessageToConversationFromUser } from '../../redux/features/conversations/conversationsSlice'; import { SharedStyles } from '../../styles'; import { ChatInput } from './ChatInput'; import { ChatHistory } from './chat-history/ChatHistory'; @@ -48,7 +48,6 @@ export const ChatRoom: React.FC = () => { const dispatch = useAppDispatch(); const scrollViewTargetRef = React.useRef(null); - const scrollTargetRef = React.useRef(null); const [shouldAutoScroll, setShouldAutoScroll] = React.useState(true); const [isDraggingOver, setIsDraggingOver] = React.useState(false); @@ -65,7 +64,7 @@ export const ChatRoom: React.FC = () => { React.useEffect(() => { if (!shouldAutoScroll) return; - scrollToTarget(scrollTargetRef.current); + scrollViewTargetRef.current?.scrollTo(0, scrollViewTargetRef.current.scrollHeight); }, [messages, shouldAutoScroll]); React.useEffect(() => { @@ -98,7 +97,7 @@ export const ChatRoom: React.FC = () => { authorRole: AuthorRoles.User, }; - dispatch(updateConversationFromUser({ message: chatInput })); + dispatch(addMessageToConversationFromUser({ message: chatInput, chatId: selectedId })); await chat.getResponse(options); @@ -108,21 +107,13 @@ export const ChatRoom: React.FC = () => { return (
-
+
-
-
-
); -}; - -const scrollToTarget = (element: HTMLElement | null) => { - if (!element) return; - element.scrollIntoView({ block: 'start', behavior: 'smooth' }); -}; +}; \ No newline at end of file diff --git a/webapp/src/components/chat/chat-history/UserFeedbackActions.tsx b/webapp/src/components/chat/chat-history/UserFeedbackActions.tsx index a766da776..98e04da2c 100644 --- a/webapp/src/components/chat/chat-history/UserFeedbackActions.tsx +++ b/webapp/src/components/chat/chat-history/UserFeedbackActions.tsx @@ -3,7 +3,7 @@ import { useCallback } from 'react'; import { UserFeedback } from '../../../libs/models/ChatMessage'; import { useAppDispatch, useAppSelector } from '../../../redux/app/hooks'; import { RootState } from '../../../redux/app/store'; -import { setUserFeedback } from '../../../redux/features/conversations/conversationsSlice'; +import { updateMessageProperty } from '../../../redux/features/conversations/conversationsSlice'; import { ThumbDislike16, ThumbLike16 } from '../../shared/BundledIcons'; const useClasses = makeStyles({ @@ -27,10 +27,12 @@ export const UserFeedbackActions: React.FC = ({ messageIndex const onUserFeedbackProvided = useCallback( (positive: boolean) => { dispatch( - setUserFeedback({ - userFeedback: positive ? UserFeedback.Positive : UserFeedback.Negative, - messageIndex, + updateMessageProperty({ chatId: selectedId, + messageIdOrIndex: messageIndex, + property: 'userFeedback', + value: positive ? UserFeedback.Positive : UserFeedback.Negative, + frontLoad: true, }), ); }, diff --git a/webapp/src/components/chat/plan-viewer/PlanViewer.tsx b/webapp/src/components/chat/plan-viewer/PlanViewer.tsx index a28c2a28e..4a999230e 100644 --- a/webapp/src/components/chat/plan-viewer/PlanViewer.tsx +++ b/webapp/src/components/chat/plan-viewer/PlanViewer.tsx @@ -7,7 +7,7 @@ import { IAskVariables } from '../../../libs/semantic-kernel/model/Ask'; import { GetResponseOptions } from '../../../libs/useChat'; import { useAppDispatch, useAppSelector } from '../../../redux/app/hooks'; import { RootState } from '../../../redux/app/store'; -import { updateMessageState } from '../../../redux/features/conversations/conversationsSlice'; +import { updateMessageProperty } from '../../../redux/features/conversations/conversationsSlice'; import { PlanStepCard } from './PlanStepCard'; const useClasses = makeStyles({ @@ -61,7 +61,7 @@ export const PlanViewer: React.FC = ({ message, messageIndex, g const parsedContent: Plan = JSON.parse(message.content); const originalPlan = parsedContent.proposedPlan; - const planState = message.state ?? parsedContent.state; + const planState = message.planState ?? parsedContent.state; // If plan came from ActionPlanner, use parameters from top-level of plan if (parsedContent.type === PlanType.Action) { @@ -79,10 +79,12 @@ export const PlanViewer: React.FC = ({ message, messageIndex, g const onPlanAction = async (planState: PlanState.PlanApproved | PlanState.PlanRejected) => { dispatch( - updateMessageState({ - newMessageState: planState, - messageIndex, + updateMessageProperty({ + messageIdOrIndex: messageIndex, chatId: selectedId, + property: 'planState', + value: planState, + frontLoad: true, }), ); diff --git a/webapp/src/libs/models/ChatMessage.ts b/webapp/src/libs/models/ChatMessage.ts index 8bc3a0c90..961d9b9b7 100644 --- a/webapp/src/libs/models/ChatMessage.ts +++ b/webapp/src/libs/models/ChatMessage.ts @@ -50,7 +50,7 @@ export interface IChatMessage { prompt?: string; authorRole: AuthorRoles; debug?: string; - state?: PlanState; + planState?: PlanState; // TODO: Persistent RLHF, view only right now userFeedback?: UserFeedback; } diff --git a/webapp/src/libs/services/ChatService.ts b/webapp/src/libs/services/ChatService.ts index f922cb733..18fa58efa 100644 --- a/webapp/src/libs/services/ChatService.ts +++ b/webapp/src/libs/services/ChatService.ts @@ -7,7 +7,6 @@ import { IChatParticipant } from '../models/ChatParticipant'; import { IChatSession } from '../models/ChatSession'; import { IChatUser } from '../models/ChatUser'; import { IAsk, IAskVariables } from '../semantic-kernel/model/Ask'; -import { IAskResult } from '../semantic-kernel/model/AskResult'; import { BaseService } from './BaseService'; export class ChatService extends BaseService { @@ -93,7 +92,7 @@ export class ChatService extends BaseService { ask: IAsk, accessToken: string, enabledPlugins?: Plugin[], - ): Promise => { + ): Promise => { // If skill requires any additional api properties, append to context if (enabledPlugins && enabledPlugins.length > 0) { const openApiSkillVariables: IAskVariables[] = []; @@ -122,7 +121,7 @@ export class ChatService extends BaseService { ask.variables = ask.variables ? ask.variables.concat(openApiSkillVariables) : openApiSkillVariables; } - const result = await this.getResponseAsync( + const result = await this.getResponseAsync( { commandPath: 'chat', method: 'POST', diff --git a/webapp/src/redux/features/conversations/conversationsSlice.ts b/webapp/src/redux/features/conversations/conversationsSlice.ts index b06ec2110..e6cb2446a 100644 --- a/webapp/src/redux/features/conversations/conversationsSlice.ts +++ b/webapp/src/redux/features/conversations/conversationsSlice.ts @@ -3,7 +3,6 @@ import { createSlice, PayloadAction, Slice } from '@reduxjs/toolkit'; import { ChatMessageType, IChatMessage, UserFeedback } from '../../../libs/models/ChatMessage'; import { IChatUser } from '../../../libs/models/ChatUser'; -import { PlanState } from '../../../libs/models/Plan'; import { ChatState } from './ChatState'; import { ConversationInputChange, @@ -51,37 +50,27 @@ export const conversationsSlice: Slice = createSlice({ state.conversations[action.payload].userDataLoaded = true; }, /* - * updateConversationFromUser() and updateConversationFromServer() both update the conversations state. + * addMessageToConversationFromUser() and addMessageToConversationFromServer() both update the conversations state. * However they are for different purposes. The former action is for updating the conversation from the * webapp and will be captured by the SignalR middleware and the payload will be broadcasted to all clients * in the same group. - * The updateConversationFromServer() action is triggered by the SignalR middleware when a response is received + * The addMessageToConversationFromServer() action is triggered by the SignalR middleware when a response is received * from the webapi. */ - updateConversationFromUser: ( + addMessageToConversationFromUser: ( state: ConversationsState, - action: PayloadAction<{ message: IChatMessage; chatId?: string }>, + action: PayloadAction<{ message: IChatMessage; chatId: string }>, ) => { const { message, chatId } = action.payload; - const id = chatId ?? state.selectedId; - updateConversation(state, id, message); + updateConversation(state, chatId, message); }, - updateConversationFromServer: ( + addMessageToConversationFromServer: ( state: ConversationsState, action: PayloadAction<{ message: IChatMessage; chatId: string }>, ) => { const { message, chatId } = action.payload; updateConversation(state, chatId, message); }, - updateMessageState: ( - state: ConversationsState, - action: PayloadAction<{ newMessageState: PlanState; messageIndex: number; chatId?: string }>, - ) => { - const { newMessageState, messageIndex, chatId } = action.payload; - const id = chatId ?? state.selectedId; - state.conversations[id].messages[messageIndex].state = newMessageState; - frontLoadChat(state, id); - }, /* * updateUserIsTyping() and updateUserIsTypingFromServer() both update a user's typing state. * However they are for different purposes. The former action is for updating an user's typing state from @@ -104,7 +93,7 @@ export const conversationsSlice: Slice = createSlice({ const { userId, chatId, isTyping } = action.payload; updateUserTypingState(state, userId, chatId, isTyping); }, - updateBotResponseStatusFromServer: ( + updateBotResponseStatus: ( state: ConversationsState, action: PayloadAction<{ chatId: string; status: string }>, ) => { @@ -112,36 +101,33 @@ export const conversationsSlice: Slice = createSlice({ const conversation = state.conversations[chatId]; conversation.botResponseStatus = status; }, - setUserFeedback: ( + updateMessageProperty: ( state: ConversationsState, - action: PayloadAction<{ userFeedback: UserFeedback; messageIndex: number; chatId?: string }>, + action: PayloadAction<{ + property: K; + value: V; + chatId: string; + messageIdOrIndex: string | number; + frontLoad?: boolean; + }>, ) => { - const { userFeedback, messageIndex, chatId } = action.payload; - const id = chatId ?? state.selectedId; - state.conversations[id].messages[messageIndex].userFeedback = userFeedback; - frontLoadChat(state, id); + const { property, value, messageIdOrIndex, chatId, frontLoad } = action.payload; + const conversation = state.conversations[chatId]; + const conversationMessage = + typeof messageIdOrIndex === 'number' + ? conversation.messages[messageIdOrIndex] + : conversation.messages.find((m) => m.id === messageIdOrIndex); + + if (conversationMessage) { + conversationMessage[property] = value; + } + if (frontLoad) { + frontLoadChat(state, chatId); + } }, }, }); -export const { - setConversations, - editConversationTitle, - editConversationInput, - setSelectedConversation, - addConversation, - updateConversationFromUser, - updateConversationFromServer, - updateMessageState, - updateUserIsTyping, - updateUserIsTypingFromServer, - updateBotResponseStatusFromServer, - setUsersLoaded, - setUserFeedback, -} = conversationsSlice.actions; - -export default conversationsSlice.reducer; - const frontLoadChat = (state: ConversationsState, id: string) => { const conversation = state.conversations[id]; const { [id]: _, ...rest } = state.conversations; @@ -164,3 +150,20 @@ const updateUserTypingState = (state: ConversationsState, userId: string, chatId user.isTyping = isTyping; } }; + +export const { + setConversations, + editConversationTitle, + editConversationInput, + setSelectedConversation, + addConversation, + addMessageToConversationFromUser, + addMessageToConversationFromServer, + updateMessageProperty, + updateUserIsTyping, + updateUserIsTypingFromServer, + updateBotResponseStatus, + setUsersLoaded, +} = conversationsSlice.actions; + +export default conversationsSlice.reducer; diff --git a/webapp/src/redux/features/message-relay/signalRMiddleware.ts b/webapp/src/redux/features/message-relay/signalRMiddleware.ts index 7efedc189..e41e6892e 100644 --- a/webapp/src/redux/features/message-relay/signalRMiddleware.ts +++ b/webapp/src/redux/features/message-relay/signalRMiddleware.ts @@ -5,7 +5,6 @@ import { AnyAction, Dispatch } from '@reduxjs/toolkit'; import { AlertType } from '../../../libs/models/AlertType'; import { IChatUser } from '../../../libs/models/ChatUser'; import { PlanState } from '../../../libs/models/Plan'; -import { IAskResult } from '../../../libs/semantic-kernel/model/AskResult'; import { addAlert } from '../app/appSlice'; import { ChatState } from '../conversations/ChatState'; import { AuthorRoles, ChatMessageType, IChatMessage } from './../../../libs/models/ChatMessage'; @@ -14,12 +13,11 @@ import { Store, StoreMiddlewareAPI, getSelectedChatID } from './../../app/store' // These have to match the callback names used in the backend const enum SignalRCallbackMethods { ReceiveMessage = 'ReceiveMessage', - ReceiveResponse = 'ReceiveResponse', + ReceiveMessageStream = 'ReceiveMessageStream', UserJoined = 'UserJoined', ReceiveUserTypingState = 'ReceiveUserTypingState', ReceiveBotResponseStatus = 'ReceiveBotResponseStatus', GlobalDocumentUploaded = 'GlobalDocumentUploaded', - ChatDocumentUploaded = 'ChatDocumentUploaded', ChatEdited = 'ChatEdited', } @@ -112,9 +110,14 @@ export const signalRMiddleware = (store: StoreMiddlewareAPI) => { // The following actions will be captured by the SignalR middleware and broadcasted to all clients. switch (action.type) { - case 'conversations/updateConversationFromUser': + case 'conversations/addMessageToConversationFromUser': hubConnection - .invoke('SendMessageAsync', getSelectedChatID(), action.payload.message) + .invoke( + 'SendMessageAsync', + getSelectedChatID(), + store.getState().app.activeUserInfo?.id, + action.payload.message, + ) .catch((err) => store.dispatch(addAlert({ message: String(err), type: AlertType.Error }))); break; case 'conversations/updateUserIsTyping': @@ -146,33 +149,31 @@ export const signalRMiddleware = (store: StoreMiddlewareAPI) => { }; export const registerSignalREvents = (store: Store) => { - hubConnection.on(SignalRCallbackMethods.ReceiveMessage, (message: IChatMessage, chatId: string) => { - store.dispatch({ type: 'conversations/updateConversationFromServer', payload: { message, chatId } }); - }); + hubConnection.on( + SignalRCallbackMethods.ReceiveMessage, + (chatId: string, senderId: string, message: IChatMessage) => { + if (message.authorRole === AuthorRoles.Bot) { + const loggedInUserId = store.getState().app.activeUserInfo?.id; + const responseToLoggedInUser = loggedInUserId === senderId; + message.planState = + message.type === ChatMessageType.Plan && responseToLoggedInUser + ? PlanState.PlanApprovalRequired + : PlanState.Disabled; + } + + store.dispatch({ type: 'conversations/addMessageToConversationFromServer', payload: { chatId, message } }); + }, + ); - hubConnection.on(SignalRCallbackMethods.ReceiveResponse, (askResult: IAskResult, chatId: string) => { - const loggedInUserId = store.getState().app.activeUserInfo?.id; - const originalMessageUserId: string | undefined = askResult.variables.find((v) => v.key === 'userId')?.value; - const isPlanForLoggedInUser = loggedInUserId === originalMessageUserId; - const messageType = Number(askResult.variables.find((v) => v.key === 'messageType')?.value) as ChatMessageType; - - const message = { - type: messageType, - timestamp: new Date().getTime(), - userName: 'bot', - userId: 'bot', - content: askResult.value, - prompt: askResult.variables.find((v) => v.key === 'prompt')?.value, - authorRole: AuthorRoles.Bot, - id: askResult.variables.find((v) => v.key === 'messageId')?.value, - state: - messageType === ChatMessageType.Plan && isPlanForLoggedInUser - ? PlanState.PlanApprovalRequired - : PlanState.Disabled, - } as IChatMessage; - - store.dispatch({ type: 'conversations/updateConversationFromServer', payload: { message, chatId } }); - }); + hubConnection.on( + SignalRCallbackMethods.ReceiveMessageStream, + (chatId: string, messageId: string, content: string) => { + store.dispatch({ + type: 'conversations/updateMessageProperty', + payload: { chatId, messageIdOrIndex: messageId, property: 'content', value: content, frontLoad: true }, + }); + }, + ); hubConnection.on(SignalRCallbackMethods.UserJoined, (chatId: string, userId: string) => { const user: IChatUser = { @@ -197,17 +198,13 @@ export const registerSignalREvents = (store: Store) => { ); hubConnection.on(SignalRCallbackMethods.ReceiveBotResponseStatus, (chatId: string, status: string) => { - store.dispatch({ type: 'conversations/updateBotResponseStatusFromServer', payload: { chatId, status } }); + store.dispatch({ type: 'conversations/updateBotResponseStatus', payload: { chatId, status } }); }); hubConnection.on(SignalRCallbackMethods.GlobalDocumentUploaded, (fileNames: string, userName: string) => { store.dispatch(addAlert({ message: `${userName} uploaded ${fileNames} to all chats`, type: AlertType.Info })); }); - hubConnection.on(SignalRCallbackMethods.ChatDocumentUploaded, (message: IChatMessage, chatId: string) => { - store.dispatch({ type: 'conversations/updateConversationFromServer', payload: { message, chatId } }); - }); - hubConnection.on(SignalRCallbackMethods.ChatEdited, (chat: ChatState) => { const { id, title } = chat; if (!(id in store.getState().conversations.conversations)) { From b8b73e5b24880d6e7c66c9752270597feb7730c5 Mon Sep 17 00:00:00 2001 From: Teresa Hoang <125500434+teresaqhoang@users.noreply.github.com> Date: Tue, 25 Jul 2023 16:38:46 -0700 Subject: [PATCH 021/582] Adding support for custom plugin import (#29) ### Motivation and Context This PR adds support for custom plugins. This implementation follows manifest requirements set by OpenAI for custom ChatGPT plugins and is defined here: https://learn.microsoft.com/en-us/semantic-kernel/ai-orchestration/chatgpt-plugins#add-the-plugin-manifest-file ### Description webapi - Added GetPluginAuthHeaders() to ChatController.cs to parse plugin auth values from request headers. This was manually parsed using hardcoded headers before. - Standardized all plugin headers to `x-sk-copilot-(.*)-auth` - Updated RegisterPlannerSkillsAsync() to accept a Dictionary of auth headers and register authenticated skills with the planner's kernel. - Added logic to register custom plugins from context variables, including support for loading custom plugins from manifest files with authentication support for user PAT and no auth. webapp - General - Added .well-known* to .gitignore. - Consolidated all hooks into `libs/hooks` directory. Updated imports accordingly - Consolidated dialog styles into shared class - Create BaseCard component to render a generic card. - Add AddPluginCard component to render a card for adding custom plugins. Card action triggers Plugin Wizard - Create PluginCard component to render a card for existing plugins. - Fix PluginGallery component to use new PluginCard and AddPluginCard components. - Update PluginConnector component to use new Dialog classes. - Remove unused code from PluginCard and PluginConnector components. - Create PluginWizard component to handle custom plugin import. Includes three steps: `EnterManifestStep`, `ValidateManifestStep`, and a confirmation page - Manifest Validation: - Domain is a valid URL (doesn't throw when constructed using new URL) - Meets all the property requirements as [defined by OpenAI](https://learn.microsoft.com/en-us/semantic-kernel/ai-orchestration/chatgpt-plugins#add-the-plugin-manifest-file) - If manifest domain is valid and user imports plugin, a new card will be added for that plugin at the end of the plugin gallery. User must explicitly enable the plugin before it's used with the planner. - If plugin is enabled, header matching x-sk-copilot-{pluginNameForModel}-auth is added to request for bot response. New Plugin Gallery look with Import card ![image](https://github.com/microsoft/chat-copilot/assets/125500434/5e3b54c4-a674-4dc2-a5d3-b2231edea2f1) New card for custom plugin added to gallery ![image](https://github.com/microsoft/chat-copilot/assets/125500434/1573a69f-8d8d-4260-ab1d-64c7feb07700) Plugin Wizard ![image](https://github.com/microsoft/chat-copilot/assets/125500434/4277b93c-3b0a-4ccc-ae40-ff5e06d21ec3) - If URL is invalid: ![image](https://github.com/microsoft/chat-copilot/assets/125500434/4ff37cc5-34e7-48c7-8814-50330c3c7da4) Validate Manifest Step ![image](https://github.com/microsoft/chat-copilot/assets/125500434/e40a7933-8e99-42a4-bd39-907fa9f5378a) - If Manifest validation fails: ![image](https://github.com/microsoft/chat-copilot/assets/125500434/4c735a40-82df-4a7d-b828-8b13c6b17ba1) Confirmation ![image](https://github.com/microsoft/chat-copilot/assets/125500434/bfa3e4e6-6d01-43a3-8ad2-ba68b5b48a01) Enabling custom Plugin ![image](https://github.com/microsoft/chat-copilot/assets/125500434/ffaed95b-822c-422b-afaa-84f5eef07d64) Once user enables plugin, sample request herader: ![image](https://github.com/microsoft/chat-copilot/assets/125500434/8e888ce7-2ebd-440c-907d-4a9270e32850) Planner integration ![image](https://github.com/microsoft/chat-copilot/assets/125500434/23e45c8b-28a4-4506-b995-c6750977e6b7) ### Contribution Checklist - [x] The code builds clean without any errors or warnings - [x] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#dev-scripts) raises no violations ~~- [ ] All unit tests pass, and I have added new tests where possible~~ - [x] I didn't break anyone :smile: --- .gitignore | 5 +- .../CopilotChat/Controllers/ChatController.cs | 96 ++++++-- webapi/CopilotChat/Models/CustomPlugin.cs | 42 ++++ .../Models/OpenApiSkillsAuthHeaders.cs | 35 --- webapp/src/App.tsx | 2 +- webapp/src/Constants.ts | 11 +- webapp/src/assets/plugin-icons/add-plugin.png | Bin 0 -> 24749 bytes webapp/src/components/chat/ChatInput.tsx | 2 +- .../src/components/chat/ChatResourceList.tsx | 2 +- webapp/src/components/chat/ChatRoom.tsx | 2 +- .../chat/chat-history/ChatHistory.tsx | 2 +- .../chat/chat-history/ChatHistoryItem.tsx | 8 +- .../components/chat/chat-list/ChatList.tsx | 3 +- .../components/chat/chat-list/NewBotMenu.tsx | 2 +- .../chat/controls/ParticipantsList.tsx | 2 +- .../components/chat/controls/ShareBotMenu.tsx | 3 +- .../InvitationJoinDialog.tsx | 2 +- .../chat/plan-viewer/PlanViewer.tsx | 2 +- .../open-api-plugins/PluginCard.tsx | 79 ------ .../open-api-plugins/PluginConnector.tsx | 41 +--- .../open-api-plugins/PluginGallery.tsx | 44 +++- .../open-api-plugins/cards/AddPluginCard.tsx | 28 +++ .../open-api-plugins/cards/BaseCard.tsx | 83 +++++++ .../open-api-plugins/cards/PluginCard.tsx | 50 ++++ .../plugin-wizard/PluginWizard.tsx | 227 ++++++++++++++++++ .../plugin-wizard/steps/EnterManifestStep.tsx | 107 +++++++++ .../steps/ValidateManifestStep.tsx | 169 +++++++++++++ webapp/src/components/shared/BundledIcons.tsx | 9 +- webapp/src/components/utils/FileUtils.ts | 15 ++ webapp/src/components/utils/PluginUtils.ts | 64 +++++ webapp/src/libs/hooks/index.ts | 4 + webapp/src/libs/{ => hooks}/useChat.ts | 50 ++-- webapp/src/libs/{ => hooks}/useFile.ts | 0 webapp/src/libs/{ => hooks}/useGraph.ts | 18 +- webapp/src/libs/hooks/usePlugins.ts | 30 +++ webapp/src/libs/models/PluginManifest.ts | 61 +++++ .../semantic-kernel/model/CustomPlugin.ts | 7 + webapp/src/libs/services/ChatService.ts | 24 ++ .../redux/features/plugins/PluginsState.ts | 141 ++++++----- .../redux/features/plugins/pluginsSlice.ts | 51 ++-- webapp/src/styles.tsx | 53 +++- 41 files changed, 1253 insertions(+), 323 deletions(-) create mode 100644 webapi/CopilotChat/Models/CustomPlugin.cs delete mode 100644 webapi/CopilotChat/Models/OpenApiSkillsAuthHeaders.cs create mode 100644 webapp/src/assets/plugin-icons/add-plugin.png delete mode 100644 webapp/src/components/open-api-plugins/PluginCard.tsx create mode 100644 webapp/src/components/open-api-plugins/cards/AddPluginCard.tsx create mode 100644 webapp/src/components/open-api-plugins/cards/BaseCard.tsx create mode 100644 webapp/src/components/open-api-plugins/cards/PluginCard.tsx create mode 100644 webapp/src/components/open-api-plugins/plugin-wizard/PluginWizard.tsx create mode 100644 webapp/src/components/open-api-plugins/plugin-wizard/steps/EnterManifestStep.tsx create mode 100644 webapp/src/components/open-api-plugins/plugin-wizard/steps/ValidateManifestStep.tsx create mode 100644 webapp/src/components/utils/FileUtils.ts create mode 100644 webapp/src/components/utils/PluginUtils.ts create mode 100644 webapp/src/libs/hooks/index.ts rename webapp/src/libs/{ => hooks}/useChat.ts (87%) rename webapp/src/libs/{ => hooks}/useFile.ts (100%) rename webapp/src/libs/{ => hooks}/useGraph.ts (91%) create mode 100644 webapp/src/libs/hooks/usePlugins.ts create mode 100644 webapp/src/libs/models/PluginManifest.ts create mode 100644 webapp/src/libs/semantic-kernel/model/CustomPlugin.ts diff --git a/.gitignore b/.gitignore index 81cd9e2d7..b6e361a29 100644 --- a/.gitignore +++ b/.gitignore @@ -477,4 +477,7 @@ playwright-report/ # Static Web App deployment config swa-cli.config.json webapp/build/ -webapp/node_modules/ \ No newline at end of file +webapp/node_modules/ + +# Custom plugin files used in webapp for testing +webapp/public/.well-known* \ No newline at end of file diff --git a/webapi/CopilotChat/Controllers/ChatController.cs b/webapi/CopilotChat/Controllers/ChatController.cs index bf9824b67..f2be4889f 100644 --- a/webapi/CopilotChat/Controllers/ChatController.cs +++ b/webapi/CopilotChat/Controllers/ChatController.cs @@ -6,6 +6,8 @@ using System.Linq; using System.Net.Http; using System.Reflection; +using System.Text.Json; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; @@ -57,7 +59,6 @@ public ChatController(ILogger logger, ITelemetryService telemetr /// Message Hub that performs the real time relay service. /// Planner to use to create function sequences. /// Prompt along with its parameters. - /// Authentication headers to connect to OpenAPI Skills. /// Results containing the response from the model. [Authorize] [Route("chat")] @@ -69,8 +70,7 @@ public async Task ChatAsync( [FromServices] IKernel kernel, [FromServices] IHubContext messageRelayHubContext, [FromServices] CopilotChatPlanner planner, - [FromBody] Ask ask, - [FromHeader] OpenApiSkillsAuthHeaders openApiSkillsAuthHeaders) + [FromBody] Ask ask) { this._logger.LogDebug("Chat request received."); @@ -82,6 +82,7 @@ public async Task ChatAsync( } // Register plugins that have been enabled + var openApiSkillsAuthHeaders = this.GetPluginAuthHeaders(this.HttpContext.Request.Headers); await this.RegisterPlannerSkillsAsync(planner, openApiSkillsAuthHeaders, contextVariables); // Get the function to invoke @@ -135,27 +136,54 @@ public async Task ChatAsync( return this.Ok(chatSkillAskResult); } + /// + /// Parse plugin auth values from request headers. + /// + private Dictionary GetPluginAuthHeaders(IHeaderDictionary headers) + { + // Create a regex to match the headers + var regex = new Regex("x-sk-copilot-(.*)-auth", RegexOptions.IgnoreCase); + + // Create a dictionary to store the matched headers and values + var openApiSkillsAuthHeaders = new Dictionary(); + + // Loop through the request headers and add the matched ones to the dictionary + foreach (var header in headers) + { + var match = regex.Match(header.Key); + if (match.Success) + { + // Use the first capture group as the key and the header value as the value + openApiSkillsAuthHeaders.Add(match.Groups[1].Value.ToUpperInvariant(), header.Value); + } + } + + return openApiSkillsAuthHeaders; + } + /// /// Register skills with the planner's kernel. /// - private async Task RegisterPlannerSkillsAsync(CopilotChatPlanner planner, OpenApiSkillsAuthHeaders openApiSkillsAuthHeaders, ContextVariables variables) + private async Task RegisterPlannerSkillsAsync(CopilotChatPlanner planner, Dictionary openApiSkillsAuthHeaders, ContextVariables variables) { // Register authenticated skills with the planner's kernel only if the request includes an auth header for the skill. // Klarna Shopping - if (openApiSkillsAuthHeaders.KlarnaAuthentication != null) + if (openApiSkillsAuthHeaders.TryGetValue("KLARNA", out string? KlarnaAuthHeader)) { + this._logger.LogInformation("Registering Klarna plugin"); + // Register the Klarna shopping ChatGPT plugin with the planner's kernel. There is no authentication required for this plugin. - await planner.Kernel.ImportChatGptPluginSkillFromUrlAsync("KlarnaShoppingSkill", new Uri("https://www.klarna.com/.well-known/ai-plugin.json"), new OpenApiSkillExecutionParameters()); + await planner.Kernel.ImportChatGptPluginSkillFromUrlAsync("KlarnaShoppingPlugin", new Uri("https://www.klarna.com/.well-known/ai-plugin.json"), new OpenApiSkillExecutionParameters()); } // GitHub - if (!string.IsNullOrWhiteSpace(openApiSkillsAuthHeaders.GithubAuthentication)) + if (openApiSkillsAuthHeaders.TryGetValue("GITHUB", out string? GithubAuthHeader)) { - this._logger.LogInformation("Enabling GitHub skill."); - BearerAuthenticationProvider authenticationProvider = new(() => Task.FromResult(openApiSkillsAuthHeaders.GithubAuthentication)); + this._logger.LogInformation("Enabling GitHub plugin."); + BearerAuthenticationProvider authenticationProvider = new(() => Task.FromResult(GithubAuthHeader)); await planner.Kernel.ImportOpenApiSkillFromFileAsync( - skillName: "GitHubSkill", + skillName: "GitHubPlugin", filePath: Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!, "CopilotChat", "Skills", "OpenApiSkills/GitHubSkill/openapi.json"), new OpenApiSkillExecutionParameters { @@ -164,10 +192,10 @@ await planner.Kernel.ImportOpenApiSkillFromFileAsync( } // Jira - if (!string.IsNullOrWhiteSpace(openApiSkillsAuthHeaders.JiraAuthentication)) + if (openApiSkillsAuthHeaders.TryGetValue("JIRA", out string? JiraAuthHeader)) { - this._logger.LogInformation("Registering Jira Skill"); - var authenticationProvider = new BasicAuthenticationProvider(() => { return Task.FromResult(openApiSkillsAuthHeaders.JiraAuthentication); }); + this._logger.LogInformation("Registering Jira plugin"); + var authenticationProvider = new BasicAuthenticationProvider(() => { return Task.FromResult(JiraAuthHeader); }); var hasServerUrlOverride = variables.TryGetValue("jira-server-url", out string? serverUrlOverride); await planner.Kernel.ImportOpenApiSkillFromFileAsync( @@ -181,16 +209,54 @@ await planner.Kernel.ImportOpenApiSkillFromFileAsync( } // Microsoft Graph - if (!string.IsNullOrWhiteSpace(openApiSkillsAuthHeaders.GraphAuthentication)) + if (openApiSkillsAuthHeaders.TryGetValue("GRAPH", out string? GraphAuthHeader)) { this._logger.LogInformation("Enabling Microsoft Graph skill(s)."); - BearerAuthenticationProvider authenticationProvider = new(() => Task.FromResult(openApiSkillsAuthHeaders.GraphAuthentication)); + BearerAuthenticationProvider authenticationProvider = new(() => Task.FromResult(GraphAuthHeader)); GraphServiceClient graphServiceClient = this.CreateGraphServiceClient(authenticationProvider.AuthenticateRequestAsync); planner.Kernel.ImportSkill(new TaskListSkill(new MicrosoftToDoConnector(graphServiceClient)), "todo"); planner.Kernel.ImportSkill(new CalendarSkill(new OutlookCalendarConnector(graphServiceClient)), "calendar"); planner.Kernel.ImportSkill(new EmailSkill(new OutlookMailConnector(graphServiceClient)), "email"); } + + if (variables.TryGetValue("customPlugins", out string? customPluginsString)) + { + CustomPlugin[]? customPlugins = JsonSerializer.Deserialize(customPluginsString); + + if (customPlugins != null) + { + foreach (CustomPlugin plugin in customPlugins) + { + if (openApiSkillsAuthHeaders.TryGetValue(plugin.AuthHeaderTag.ToUpperInvariant(), out string? PluginAuthValue)) + { + // Register the ChatGPT plugin with the planner's kernel. + this._logger.LogInformation("Enabling {0} plugin.", plugin.NameForHuman); + + UriBuilder uriBuilder = new(plugin.ManifestDomain); + // Expected manifest path as defined by OpenAI: https://platform.openai.com/docs/plugins/getting-started/plugin-manifest + uriBuilder.Path = "/.well-known/ai-plugin.json"; + + // TODO: Support other forms of auth. Currently, we only support user PAT or no auth. + var requiresAuth = !plugin.AuthType.Equals("none", StringComparison.OrdinalIgnoreCase); + BearerAuthenticationProvider authenticationProvider = new(() => Task.FromResult(PluginAuthValue)); + + await planner.Kernel.ImportChatGptPluginSkillFromUrlAsync( + $"{plugin.NameForModel}Plugin", + uriBuilder.Uri, + new OpenApiSkillExecutionParameters + { + IgnoreNonCompliantErrors = true, + AuthCallback = requiresAuth ? authenticationProvider.AuthenticateRequestAsync : null + }); + } + } + } + else + { + this._logger.LogDebug("Failed to deserialize custom plugin details: {0}", customPluginsString); + } + } } /// diff --git a/webapi/CopilotChat/Models/CustomPlugin.cs b/webapi/CopilotChat/Models/CustomPlugin.cs new file mode 100644 index 000000000..b3c3ebb12 --- /dev/null +++ b/webapi/CopilotChat/Models/CustomPlugin.cs @@ -0,0 +1,42 @@ +// Copyright (c) Microsoft. All rights reserved. +using System.Text.Json.Serialization; + +namespace SemanticKernel.Service.CopilotChat.Models; + +/// +/// Custom plugin imported from ChatGPT Manifest file. +/// Docs: https://platform.openai.com/docs/plugins/introduction. +/// +public class CustomPlugin +{ + /// + /// Human-readable name, such as the full company name. + /// + [JsonPropertyName("nameForHuman")] + public string NameForHuman { get; set; } = string.Empty; + + /// + /// Name the model will use to target the plugin. + /// + [JsonPropertyName("nameForModel")] + public string NameForModel { get; set; } = string.Empty; + + /// + /// Expected request header tag containing auth information. + /// + [JsonPropertyName("authHeaderTag")] + public string AuthHeaderTag { get; set; } = string.Empty; + + /// + /// Auth type. Currently limited to either 'none' + /// or user PAT (https://platform.openai.com/docs/plugins/authentication/user-level) + /// + [JsonPropertyName("authType")] + public string AuthType { get; set; } = string.Empty; + + /// + /// Website domain hosting the plugin files. + /// + [JsonPropertyName("manifestDomain")] + public string ManifestDomain { get; set; } = string.Empty; +} diff --git a/webapi/CopilotChat/Models/OpenApiSkillsAuthHeaders.cs b/webapi/CopilotChat/Models/OpenApiSkillsAuthHeaders.cs deleted file mode 100644 index bac14f65a..000000000 --- a/webapi/CopilotChat/Models/OpenApiSkillsAuthHeaders.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright (c) Microsoft. All rights reserved. - -using Microsoft.AspNetCore.Mvc; - -namespace SemanticKernel.Service.CopilotChat.Models; - -/// /// -/// Represents the authentication headers for imported OpenAPI Plugin Skills. -/// -public class OpenApiSkillsAuthHeaders -{ - /// - /// Gets or sets the MS Graph authentication header value. - /// - [FromHeader(Name = "x-sk-copilot-graph-auth")] - public string? GraphAuthentication { get; set; } - - /// - /// Gets or sets the Jira authentication header value. - /// - [FromHeader(Name = "x-sk-copilot-jira-auth")] - public string? JiraAuthentication { get; set; } - - /// - /// Gets or sets the GitHub authentication header value. - /// - [FromHeader(Name = "x-sk-copilot-github-auth")] - public string? GithubAuthentication { get; set; } - - /// - /// Gets or sets the Klarna header value. - /// - [FromHeader(Name = "x-sk-copilot-klarna-auth")] - public string? KlarnaAuthentication { get; set; } -} diff --git a/webapp/src/App.tsx b/webapp/src/App.tsx index 7a3a682c7..b519ba066 100644 --- a/webapp/src/App.tsx +++ b/webapp/src/App.tsx @@ -12,7 +12,7 @@ import { ChatView } from './components/views/ChatView'; import Loading from './components/views/Loading'; import { Login } from './components/views/Login'; import { AlertType } from './libs/models/AlertType'; -import { useChat } from './libs/useChat'; +import { useChat } from './libs/hooks'; import { useAppDispatch, useAppSelector } from './redux/app/hooks'; import { RootState } from './redux/app/store'; import { addAlert, setActiveUserInfo } from './redux/features/app/appSlice'; diff --git a/webapp/src/Constants.ts b/webapp/src/Constants.ts index f4a83b9ba..334ac8bad 100644 --- a/webapp/src/Constants.ts +++ b/webapp/src/Constants.ts @@ -39,9 +39,14 @@ export const Constants = { // Reserved context variable names reservedWords: ['server_url', 'server-url'], }, - // For a list of Microsoft Graph permissions, see https://learn.microsoft.com/en-us/graph/permissions-reference. - // Your application registration will need to be granted these permissions in Azure Active Directory. - msGraphPluginScopes: ['Calendars.Read', 'Mail.Read', 'Mail.Send', 'Tasks.ReadWrite', 'User.Read'], adoScopes: ['vso.work'], BATCH_REQUEST_LIMIT: 20, + plugins: { + // For a list of Microsoft Graph permissions, see https://learn.microsoft.com/en-us/graph/permissions-reference. + // Your application registration will need to be granted these permissions in Azure Active Directory. + msGraphScopes: ['Calendars.Read', 'Mail.Read', 'Mail.Send', 'Tasks.ReadWrite', 'User.Read'], + // All OpenAI plugin manifest files should be located at this path per OpenAI requirements: "https://platform.openai.com/docs/plugins/getting-started/plugin-manifest + MANIFEST_PATH: '/.well-known/ai-plugin.json', + }, + KEYSTROKE_DEBOUNCE_TIME_MS: 250 }; diff --git a/webapp/src/assets/plugin-icons/add-plugin.png b/webapp/src/assets/plugin-icons/add-plugin.png new file mode 100644 index 0000000000000000000000000000000000000000..4af1151b65c6db91359ed93112d920631a7e96bd GIT binary patch literal 24749 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 M07*qoM6N<$f&_DUVgLXD literal 0 HcmV?d00001 diff --git a/webapp/src/components/chat/ChatInput.tsx b/webapp/src/components/chat/ChatInput.tsx index 55a1c191e..e29c417d2 100644 --- a/webapp/src/components/chat/ChatInput.tsx +++ b/webapp/src/components/chat/ChatInput.tsx @@ -10,7 +10,7 @@ import { Constants } from '../../Constants'; import { AuthHelper } from '../../libs/auth/AuthHelper'; import { AlertType } from '../../libs/models/AlertType'; import { ChatMessageType } from '../../libs/models/ChatMessage'; -import { GetResponseOptions, useChat } from '../../libs/useChat'; +import { GetResponseOptions, useChat } from '../../libs/hooks/useChat'; import { useAppDispatch, useAppSelector } from '../../redux/app/hooks'; import { RootState } from '../../redux/app/store'; import { addAlert } from '../../redux/features/app/appSlice'; diff --git a/webapp/src/components/chat/ChatResourceList.tsx b/webapp/src/components/chat/ChatResourceList.tsx index efc4ae1b9..4914f958f 100644 --- a/webapp/src/components/chat/ChatResourceList.tsx +++ b/webapp/src/components/chat/ChatResourceList.tsx @@ -21,7 +21,7 @@ import { import { DocumentPdfRegular, DocumentTextRegular, FluentIconsProps } from '@fluentui/react-icons'; import * as React from 'react'; import { ChatMemorySource } from '../../libs/models/ChatMemorySource'; -import { useChat } from '../../libs/useChat'; +import { useChat } from '../../libs/hooks'; import { SharedStyles } from '../../styles'; import { timestampToDateString } from '../utils/TextUtils'; diff --git a/webapp/src/components/chat/ChatRoom.tsx b/webapp/src/components/chat/ChatRoom.tsx index 6645a6a94..1d23dd47a 100644 --- a/webapp/src/components/chat/ChatRoom.tsx +++ b/webapp/src/components/chat/ChatRoom.tsx @@ -5,7 +5,7 @@ import debug from 'debug'; import React from 'react'; import { Constants } from '../../Constants'; import { AuthorRoles, IChatMessage } from '../../libs/models/ChatMessage'; -import { GetResponseOptions, useChat } from '../../libs/useChat'; +import { GetResponseOptions, useChat } from '../../libs/hooks/useChat'; import { useAppDispatch, useAppSelector } from '../../redux/app/hooks'; import { RootState } from '../../redux/app/store'; import { addMessageToConversationFromUser } from '../../redux/features/conversations/conversationsSlice'; diff --git a/webapp/src/components/chat/chat-history/ChatHistory.tsx b/webapp/src/components/chat/chat-history/ChatHistory.tsx index 21fba767c..8ff90172c 100644 --- a/webapp/src/components/chat/chat-history/ChatHistory.tsx +++ b/webapp/src/components/chat/chat-history/ChatHistory.tsx @@ -3,7 +3,7 @@ import { makeStyles, shorthands, tokens } from '@fluentui/react-components'; import React from 'react'; import { IChatMessage } from '../../../libs/models/ChatMessage'; -import { GetResponseOptions } from '../../../libs/useChat'; +import { GetResponseOptions } from '../../../libs/hooks/useChat'; import { ChatHistoryItem } from './ChatHistoryItem'; const useClasses = makeStyles({ diff --git a/webapp/src/components/chat/chat-history/ChatHistoryItem.tsx b/webapp/src/components/chat/chat-history/ChatHistoryItem.tsx index b9a61bdd3..3b45e8aac 100644 --- a/webapp/src/components/chat/chat-history/ChatHistoryItem.tsx +++ b/webapp/src/components/chat/chat-history/ChatHistoryItem.tsx @@ -1,19 +1,19 @@ // Copyright (c) Microsoft. All rights reserved. import { Persona, Text, makeStyles, mergeClasses, shorthands, tokens } from '@fluentui/react-components'; +import { ThumbDislike24Filled, ThumbLike16Filled } from '@fluentui/react-icons'; import React from 'react'; +import { GetResponseOptions, useChat } from '../../../libs/hooks/useChat'; import { AuthorRoles, ChatMessageType, IChatMessage, UserFeedback } from '../../../libs/models/ChatMessage'; -import { GetResponseOptions, useChat } from '../../../libs/useChat'; import { useAppSelector } from '../../../redux/app/hooks'; import { RootState } from '../../../redux/app/store'; import { Breakpoints, customTokens } from '../../../styles'; import { timestampToDateString } from '../../utils/TextUtils'; import { PlanViewer } from '../plan-viewer/PlanViewer'; import { PromptDetails } from '../prompt-details/PromptDetails'; +import * as utils from './../../utils/TextUtils'; import { ChatHistoryDocumentContent } from './ChatHistoryDocumentContent'; import { ChatHistoryTextContent } from './ChatHistoryTextContent'; -import * as utils from './../../utils/TextUtils'; -import { ThumbLike16Filled, ThumbDislike24Filled } from '@fluentui/react-icons'; import { UserFeedbackActions } from './UserFeedbackActions'; const useClasses = makeStyles({ @@ -44,7 +44,7 @@ const useClasses = makeStyles({ ...shorthands.padding(tokens.spacingVerticalS, tokens.spacingHorizontalL), }, me: { - backgroundColor: "#e8ebf9", + backgroundColor: '#e8ebf9', }, time: { color: tokens.colorNeutralForeground3, diff --git a/webapp/src/components/chat/chat-list/ChatList.tsx b/webapp/src/components/chat/chat-list/ChatList.tsx index d733fdcc2..05ec696cd 100644 --- a/webapp/src/components/chat/chat-list/ChatList.tsx +++ b/webapp/src/components/chat/chat-list/ChatList.tsx @@ -15,8 +15,7 @@ import { FC, useCallback, useEffect, useRef, useState } from 'react'; import { AlertType } from '../../../libs/models/AlertType'; import { Bot } from '../../../libs/models/Bot'; import { ChatMessageType } from '../../../libs/models/ChatMessage'; -import { useChat } from '../../../libs/useChat'; -import { useFile } from '../../../libs/useFile'; +import { useChat, useFile } from '../../../libs/hooks'; import { isPlan } from '../../../libs/utils/PlanUtils'; import { useAppDispatch, useAppSelector } from '../../../redux/app/hooks'; import { RootState } from '../../../redux/app/store'; diff --git a/webapp/src/components/chat/chat-list/NewBotMenu.tsx b/webapp/src/components/chat/chat-list/NewBotMenu.tsx index 6010290d0..e2a692869 100644 --- a/webapp/src/components/chat/chat-list/NewBotMenu.tsx +++ b/webapp/src/components/chat/chat-list/NewBotMenu.tsx @@ -10,7 +10,7 @@ import { PeopleTeamAddRegular, bundleIcon, } from '@fluentui/react-icons'; -import { useChat } from '../../../libs/useChat'; +import { useChat } from '../../../libs/hooks'; import { InvitationJoinDialog } from '../invitation-dialog/InvitationJoinDialog'; interface NewBotMenuProps { diff --git a/webapp/src/components/chat/controls/ParticipantsList.tsx b/webapp/src/components/chat/controls/ParticipantsList.tsx index e56ee9e88..4d47e0c75 100644 --- a/webapp/src/components/chat/controls/ParticipantsList.tsx +++ b/webapp/src/components/chat/controls/ParticipantsList.tsx @@ -14,7 +14,7 @@ import { tokens, } from '@fluentui/react-components'; import { IChatUser } from '../../../libs/models/ChatUser'; -import { useGraph } from '../../../libs/useGraph'; +import { useGraph } from '../../../libs/hooks'; import { useAppDispatch, useAppSelector } from '../../../redux/app/hooks'; import { RootState } from '../../../redux/app/store'; import { setUsersLoaded } from '../../../redux/features/conversations/conversationsSlice'; diff --git a/webapp/src/components/chat/controls/ShareBotMenu.tsx b/webapp/src/components/chat/controls/ShareBotMenu.tsx index 3d8000f7a..ba7d9991a 100644 --- a/webapp/src/components/chat/controls/ShareBotMenu.tsx +++ b/webapp/src/components/chat/controls/ShareBotMenu.tsx @@ -4,8 +4,7 @@ import React, { FC, useCallback } from 'react'; import { Button, Menu, MenuItem, MenuList, MenuPopover, MenuTrigger, Tooltip } from '@fluentui/react-components'; import { ArrowDownloadRegular, PeopleTeamAddRegular, ShareRegular } from '@fluentui/react-icons'; -import { useChat } from '../../../libs/useChat'; -import { useFile } from '../../../libs/useFile'; +import { useChat, useFile } from '../../../libs/hooks'; import { InvitationCreateDialog } from '../invitation-dialog/InvitationCreateDialog'; interface ShareBotMenuProps { diff --git a/webapp/src/components/chat/invitation-dialog/InvitationJoinDialog.tsx b/webapp/src/components/chat/invitation-dialog/InvitationJoinDialog.tsx index d3211b91e..9a2acfc4a 100644 --- a/webapp/src/components/chat/invitation-dialog/InvitationJoinDialog.tsx +++ b/webapp/src/components/chat/invitation-dialog/InvitationJoinDialog.tsx @@ -14,7 +14,7 @@ import { tokens, } from '@fluentui/react-components'; import React from 'react'; -import { useChat } from '../../../libs/useChat'; +import { useChat } from '../../../libs/hooks'; const useStyles = makeStyles({ content: { diff --git a/webapp/src/components/chat/plan-viewer/PlanViewer.tsx b/webapp/src/components/chat/plan-viewer/PlanViewer.tsx index 4a999230e..c47b4a6b5 100644 --- a/webapp/src/components/chat/plan-viewer/PlanViewer.tsx +++ b/webapp/src/components/chat/plan-viewer/PlanViewer.tsx @@ -4,7 +4,7 @@ import { useState } from 'react'; import { ChatMessageType, IChatMessage } from '../../../libs/models/ChatMessage'; import { IPlanInput, PlanState, PlanType } from '../../../libs/models/Plan'; import { IAskVariables } from '../../../libs/semantic-kernel/model/Ask'; -import { GetResponseOptions } from '../../../libs/useChat'; +import { GetResponseOptions } from '../../../libs/hooks/useChat'; import { useAppDispatch, useAppSelector } from '../../../redux/app/hooks'; import { RootState } from '../../../redux/app/store'; import { updateMessageProperty } from '../../../redux/features/conversations/conversationsSlice'; diff --git a/webapp/src/components/open-api-plugins/PluginCard.tsx b/webapp/src/components/open-api-plugins/PluginCard.tsx deleted file mode 100644 index 7474f795b..000000000 --- a/webapp/src/components/open-api-plugins/PluginCard.tsx +++ /dev/null @@ -1,79 +0,0 @@ -import { Button, Caption1, Card, CardHeader, Text, makeStyles, shorthands, tokens } from '@fluentui/react-components'; -import { FormEvent } from 'react'; -import { useAppDispatch } from '../../redux/app/hooks'; -import { Plugin } from '../../redux/features/plugins/PluginsState'; -import { disconnectPlugin } from '../../redux/features/plugins/pluginsSlice'; -import { PluginConnector } from './PluginConnector'; - -const useStyles = makeStyles({ - main: { - ...shorthands.gap('36px'), - display: 'flex', - flexDirection: 'column', - flexWrap: 'wrap', - }, - title: { - ...shorthands.margin(0, 0, '12px'), - }, - description: { - ...shorthands.margin(0, 0, '12px'), - }, - card: { - width: '480px', - maxWidth: '100%', - height: '124px', - }, - caption: { - color: tokens.colorNeutralForeground3, - }, - logo: { - ...shorthands.borderRadius('4px'), - width: '48px', - height: '48px', - }, - text: { - ...shorthands.margin(0), - }, -}); - -interface PluginCardProps { - plugin: Plugin; -} - -export const PluginCard: React.FC = ({ plugin }) => { - const { name, publisher, enabled, authRequirements, apiProperties, icon, description } = plugin; - - const styles = useStyles(); - const dispatch = useAppDispatch(); - - const onDisconnectClick = (event: FormEvent) => { - event.preventDefault(); - dispatch(disconnectPlugin(name)); - }; - - return ( - - } - header={{name}} - description={{publisher}} - action={ - enabled ? ( - - ) : ( - - ) - } - /> -

{description}

-
- ); -}; diff --git a/webapp/src/components/open-api-plugins/PluginConnector.tsx b/webapp/src/components/open-api-plugins/PluginConnector.tsx index d9311b761..bd9979334 100644 --- a/webapp/src/components/open-api-plugins/PluginConnector.tsx +++ b/webapp/src/components/open-api-plugins/PluginConnector.tsx @@ -13,43 +13,17 @@ import { Input, Persona, Text, - makeStyles, } from '@fluentui/react-components'; import { Dismiss20Regular } from '@fluentui/react-icons'; import { FormEvent, useState } from 'react'; import { TokenHelper } from '../../libs/auth/TokenHelper'; import { useAppDispatch } from '../../redux/app/hooks'; -import { AdditionalApiProperties, PluginAuthRequirements, Plugins } from '../../redux/features/plugins/PluginsState'; +import { AdditionalApiProperties, PluginAuthRequirements } from '../../redux/features/plugins/PluginsState'; import { connectPlugin } from '../../redux/features/plugins/pluginsSlice'; - -const useClasses = makeStyles({ - root: { - height: '515px', - }, - content: { - display: 'flex', - flexDirection: 'column', - rowGap: '10px', - }, - scopes: { - display: 'flex', - flexDirection: 'column', - rowGap: '5px', - paddingLeft: '20px', - }, - error: { - color: '#d13438', - }, - section: { - display: 'flex', - flexDirection: 'column', - width: '100%', - rowGap: '10px', - }, -}); +import { useDialogClasses } from '../../styles'; interface PluginConnectorProps { - name: Plugins; + name: string; icon: string; publisher: string; authRequirements: PluginAuthRequirements; @@ -63,7 +37,7 @@ export const PluginConnector: React.FC = ({ authRequirements, apiProperties, }) => { - const classes = useClasses(); + const classes = useDialogClasses(); const usernameRequired = !!authRequirements.username; const emailRequired = !!authRequirements.email; @@ -287,7 +261,12 @@ export const PluginConnector: React.FC = ({ - diff --git a/webapp/src/components/open-api-plugins/PluginGallery.tsx b/webapp/src/components/open-api-plugins/PluginGallery.tsx index e2b34617f..e7211985d 100644 --- a/webapp/src/components/open-api-plugins/PluginGallery.tsx +++ b/webapp/src/components/open-api-plugins/PluginGallery.tsx @@ -7,17 +7,20 @@ import { DialogSurface, DialogTitle, DialogTrigger, + Label, + Link, Subtitle1, Subtitle2, makeStyles, shorthands, tokens, } from '@fluentui/react-components'; -import { AppsAddIn24Regular, Dismiss24Regular } from '@fluentui/react-icons'; import { useState } from 'react'; import { useAppSelector } from '../../redux/app/hooks'; import { RootState } from '../../redux/app/store'; -import { PluginCard } from './PluginCard'; +import { AppsAddIn24, Dismiss24 } from '../shared/BundledIcons'; +import { AddPluginCard } from './cards/AddPluginCard'; +import { PluginCard } from './cards/PluginCard'; const useClasses = makeStyles({ root: { @@ -55,40 +58,65 @@ const useClasses = makeStyles({ export const PluginGallery: React.FC = () => { const classes = useClasses(); - const plugins = useAppSelector((state: RootState) => state.plugins); + const { plugins } = useAppSelector((state: RootState) => state.plugins); const [open, setOpen] = useState(false); return ( - { setOpen(data.open); }}> + { + setOpen(data.open); + }} + > - - + ) : ( + + ) + } + /> + ); +}; diff --git a/webapp/src/components/open-api-plugins/plugin-wizard/PluginWizard.tsx b/webapp/src/components/open-api-plugins/plugin-wizard/PluginWizard.tsx new file mode 100644 index 000000000..7b0360269 --- /dev/null +++ b/webapp/src/components/open-api-plugins/plugin-wizard/PluginWizard.tsx @@ -0,0 +1,227 @@ +import { + Button, + Dialog, + DialogActions, + DialogBody, + DialogContent, + DialogSurface, + DialogTitle, + DialogTrigger, + Persona, + Text, + makeStyles, + tokens, +} from '@fluentui/react-components'; +import { CheckmarkCircle48Regular, Dismiss24Regular } from '@fluentui/react-icons'; +import React, { ReactElement, useCallback, useState } from 'react'; +import AddPluginIcon from '../../../assets/plugin-icons/add-plugin.png'; +import { usePlugins } from '../../../libs/hooks'; +import { PluginManifest } from '../../../libs/models/PluginManifest'; +import { useDialogClasses } from '../../../styles'; +import { EnterManifestStep } from './steps/EnterManifestStep'; +import { ValidateManifestStep } from './steps/ValidateManifestStep'; + +export const useClasses = makeStyles({ + root: { + height: '400px', + }, + surface: { + width: '500px', + }, + center: { + paddingTop: '75px', + display: 'flex', + flexDirection: 'column', + alignItems: 'center', + rowGap: tokens.spacingVerticalL, + 'place-self': 'center', + width: '90%', + }, +}); + +interface IWizardStep { + id: CreatePluginSteps; + header?: ReactElement; + body: ReactElement; + buttons?: ReactElement; +} + +enum CreatePluginSteps { + EnterManifest, + ValidateManifest, + Confirmation, +} + +export const PluginWizard: React.FC = () => { + const classes = useClasses(); + const dialogClasses = useDialogClasses(); + const plugins = usePlugins(); + + const [activeStep, setActiveStep] = useState(CreatePluginSteps.EnterManifest); + const [manifestDomain, setManifestDomain] = useState(); + const [manifestDomainError, setManifestDomainError] = useState(); + const [pluginValidated, setPluginValidated] = useState(false); + const [pluginManifest, setPluginManifest] = useState(); + + // Resets wizard to first step and blank slate + const resetLocalState = useCallback(() => { + setManifestDomain(undefined); + setManifestDomainError(undefined); + setActiveStep(CreatePluginSteps.EnterManifest); + setPluginValidated(false); + }, []); + + const onAddPlugin = useCallback(() => { + if (pluginManifest && manifestDomain) { + plugins.addCustomPlugin(pluginManifest, manifestDomain); + setActiveStep(CreatePluginSteps.Confirmation); + } else { + setPluginValidated(false); + // TODO: [Issue #1973] add error handling + } + }, [pluginManifest, manifestDomain, plugins]); + + const onPluginValidated = useCallback(() => { + setPluginValidated(true); + }, []); + + const onManifestValidated = useCallback((manifest: PluginManifest) => { + setPluginManifest(manifest); + }, []); + + const setDomainUrl = useCallback((domain: string, error?: string) => { + setManifestDomain(domain); + setManifestDomainError(error); + }, []); + + const wizardSteps: IWizardStep[] = [ + { + id: CreatePluginSteps.EnterManifest, + header: ( + + ), + body: ( + + ), + buttons: ( + <> + + + + + + ), + }, + { + id: CreatePluginSteps.ValidateManifest, + header: <>Verify Plugin, + body: ( + + ), + buttons: ( + <> + + + + ), + }, + { + id: CreatePluginSteps.Confirmation, + body: ( +
+ + + Your plugin has been added successfully! Navigate back to the Gallery to enable it. + + + + +
+ ), + }, + ]; + + const currentStep = wizardSteps[activeStep]; + + return ( + { + resetLocalState(); + }} + modalType="alert" + > + + + + + + + + ); +}; diff --git a/webapp/src/components/open-api-plugins/plugin-wizard/steps/EnterManifestStep.tsx b/webapp/src/components/open-api-plugins/plugin-wizard/steps/EnterManifestStep.tsx new file mode 100644 index 000000000..939dac4be --- /dev/null +++ b/webapp/src/components/open-api-plugins/plugin-wizard/steps/EnterManifestStep.tsx @@ -0,0 +1,107 @@ +import { Body1, Input, InputOnChangeData, Subtitle1, Text, makeStyles, tokens } from '@fluentui/react-components'; +import { ErrorCircle16Regular } from '@fluentui/react-icons'; +import { useCallback, useRef, useState } from 'react'; +import { Constants } from '../../../../Constants'; + +export const useClasses = makeStyles({ + error: { + display: 'flex', + color: tokens.colorPaletteRedBorderActive, + columnGap: tokens.spacingHorizontalS, + alignItems: 'center', + }, +}); + +interface IEnterManifestStepProps { + setDomainUrl: (domain: string, error?: string) => void; + manifestDomain?: string; + manifestDomainError?: string; +} + +export const EnterManifestStep: React.FC = ({ + setDomainUrl, + manifestDomain, + manifestDomainError, +}) => { + const classes = useClasses(); + const [input, setInput] = useState( manifestDomain ?? ''); + + const keyStrokeTimeout = useRef(-1); + + const onInputChange = useCallback( + (ev: React.ChangeEvent, data: InputOnChangeData) => { + ev.preventDefault(); + setDomainUrl(data.value); + setInput(data.value); + + window.clearTimeout(keyStrokeTimeout.current); + + keyStrokeTimeout.current = window.setTimeout(() => { + try { + const validUrl = new URL(data.value); + setDomainUrl(validUrl.toString(), undefined); + } catch (e) { + setDomainUrl(data.value, 'Domain is an invalid URL.'); + } + }, Constants.KEYSTROKE_DEBOUNCE_TIME_MS); + }, + [setDomainUrl], + ); + + return ( + <> + Enter your website domain + + To connect a plugin, provide the website domain where your{' '} + + OpenAI plugin manifest + {' '} + is hosted. This is the{' '} + + ai-plugin.json + {' '} + file. + + + {manifestDomainError && ( +
+ + {manifestDomainError} +
+ )} + + Note: Chat Copilot currently only supports plugins requiring{' '} + + no auth + {' '} + or{' '} + + user-level + {' '} + authentication. + + + ); +}; + +export default EnterManifestStep; diff --git a/webapp/src/components/open-api-plugins/plugin-wizard/steps/ValidateManifestStep.tsx b/webapp/src/components/open-api-plugins/plugin-wizard/steps/ValidateManifestStep.tsx new file mode 100644 index 000000000..a14601f84 --- /dev/null +++ b/webapp/src/components/open-api-plugins/plugin-wizard/steps/ValidateManifestStep.tsx @@ -0,0 +1,169 @@ +import { + Accordion, + AccordionHeader, + AccordionItem, + AccordionPanel, + Body1, + Body2, + Spinner, + makeStyles, + shorthands, + tokens, +} from '@fluentui/react-components'; +import { CheckmarkCircle20Regular, DismissCircle20Regular } from '@fluentui/react-icons'; +import { useEffect, useState } from 'react'; +import { Constants } from '../../../../Constants'; +import { PluginManifest } from '../../../../libs/models/PluginManifest'; +import { isValidOpenAPISpec, isValidPluginManifest } from '../../../utils/PluginUtils'; +import { fetchJson } from '../../../utils/FileUtils'; + +const useClasses = makeStyles({ + start: { + justifyContent: 'start', + }, + status: { + display: 'flex', + flexDirection: 'row', + alignItems: 'center', + ...shorthands.gap(tokens.spacingHorizontalMNudge), + }, + details: { + paddingLeft: tokens.spacingHorizontalXXXL, + }, +}); + +enum FileType { + Manifest = 'OpenAI manifest', + OpenApiSpec = 'OpenAPI spec', +} + +enum ValidationState { + InputRequired, + Loading, + Success, + Failed, +} + +interface IValidateManifestStepProps { + manifestDomain?: string; + onPluginValidated: () => void; + pluginManifest?: PluginManifest; + onManifestValidated: (manifest: PluginManifest) => void; +} + +export const ValidateManifestStep: React.FC = ({ + manifestDomain, + onPluginValidated, + pluginManifest, + onManifestValidated, +}) => { + const classes = useClasses(); + const [errorMessage, setErrorMessage] = useState(); + + const [manifestValidationState, setManifestValidationState] = useState(ValidationState.Loading); + const [openApiSpecValidationState, setOpenApiSpecValidationState] = useState(ValidationState.InputRequired); + + const onManifestValidationFailed = (errorMessage: string) => { + setManifestValidationState(ValidationState.Failed); + setErrorMessage(errorMessage); + }; + + useEffect(() => { + setErrorMessage(undefined); + + try { + const manifestUrl = new URL(Constants.plugins.MANIFEST_PATH, manifestDomain); + void fetchJson(manifestUrl) + .then(async (response: Response) => { + const pluginManifest = (await response.json()) as PluginManifest; + + if (isValidPluginManifest(pluginManifest)) { + setManifestValidationState(ValidationState.Success); + setOpenApiSpecValidationState(ValidationState.Loading); + onManifestValidated(pluginManifest); + + try { + if (isValidOpenAPISpec(pluginManifest.api.url)) { + onPluginValidated(); + } + setOpenApiSpecValidationState(ValidationState.Success); + } catch (e: any) { + setOpenApiSpecValidationState(ValidationState.Failed); + setErrorMessage((e as Error).message); + } + } + }) + .catch((e) => { + onManifestValidationFailed((e as Error).message); + }); + } catch (e: unknown) { + onManifestValidationFailed((e as Error).message); + } + }, [manifestDomain, onManifestValidated, onPluginValidated]); + + const statusComponent = (type: FileType, status: ValidationState) => { + const fileType = type; + switch (status) { + case ValidationState.Loading: + return ( + + ); + case ValidationState.Failed: + case ValidationState.Success: { + const icon = + status === ValidationState.Success ? ( + + ) : ( + + ); + const text = + status === ValidationState.Success ? `Validated ${fileType}` : `Could not validate ${fileType}.`; + + return ( + + +
+ {icon} + {text} +
+
+ + { + status === ValidationState.Failed && {errorMessage} + // TODO: [Issue #1973] Add Manifest details + } + {status === ValidationState.Success && + (type === FileType.Manifest ? ( +
+ Plugin: {pluginManifest?.name_for_human} +
+ Contact: {pluginManifest?.contact_email} +
+ Auth: {pluginManifest?.auth.type} +
+ ) : ( +
+ {pluginManifest?.api.url} +
+ ))} +
+
+ ); + } + default: + return; + } + }; + + return ( + + {statusComponent(FileType.Manifest, manifestValidationState)} + {statusComponent(FileType.OpenApiSpec, openApiSpecValidationState)} + + ); +}; diff --git a/webapp/src/components/shared/BundledIcons.tsx b/webapp/src/components/shared/BundledIcons.tsx index b18dd355c..7a10d1f96 100644 --- a/webapp/src/components/shared/BundledIcons.tsx +++ b/webapp/src/components/shared/BundledIcons.tsx @@ -15,6 +15,8 @@ import { Dismiss16Regular, Dismiss20Filled, Dismiss20Regular, + Dismiss24Filled, + Dismiss24Regular, EditFilled, EditRegular, Filter20Filled, @@ -32,15 +34,16 @@ import { export const Add20 = bundleIcon(Add20Filled, Add20Regular); export const AppsAddIn24 = bundleIcon(AppsAddIn24Filled, AppsAddIn24Regular); +export const ArrowDownload16 = bundleIcon(ArrowDownload16Filled, ArrowDownload16Regular); export const BotAdd20 = bundleIcon(BotAdd20Filled, BotAdd20Regular); export const Checkmark20 = bundleIcon(Checkmark20Filled, Checkmark20Regular); export const Delete16 = bundleIcon(Delete16Filled, Delete16Regular); export const Dismiss16 = bundleIcon(Dismiss16Filled, Dismiss16Regular); export const Dismiss20 = bundleIcon(Dismiss20Filled, Dismiss20Regular); -export const Filter20 = bundleIcon(Filter20Filled, Filter20Regular); +export const Dismiss24 = bundleIcon(Dismiss24Filled, Dismiss24Regular); export const Edit = bundleIcon(EditFilled, EditRegular); -export const ArrowDownload16 = bundleIcon(ArrowDownload16Filled, ArrowDownload16Regular); -export const Share20 = bundleIcon(Share20Filled, Share20Regular); +export const Filter20 = bundleIcon(Filter20Filled, Filter20Regular); export const Info16 = bundleIcon(Info16Filled, Info16Regular); +export const Share20 = bundleIcon(Share20Filled, Share20Regular); export const ThumbLike16 = bundleIcon(ThumbLike16Filled, ThumbLike16Regular); export const ThumbDislike16 = bundleIcon(ThumbDislike16Filled, ThumbDislike16Regular); diff --git a/webapp/src/components/utils/FileUtils.ts b/webapp/src/components/utils/FileUtils.ts new file mode 100644 index 000000000..da94bc6a9 --- /dev/null +++ b/webapp/src/components/utils/FileUtils.ts @@ -0,0 +1,15 @@ +// Function that fetches and parses a JSON file +export const fetchJson = async (filePath: URL): Promise => { + try { + // Make a GET request to the file URL + const response = await fetch(filePath); + + if (response.ok) { + return response; + } else { + throw new Error(`Failed to fetch ${filePath.toString()}: ${response.status}`); + } + } catch (err) { + throw new Error(`Failed to fetch ${filePath.toString()}`); + } +}; diff --git a/webapp/src/components/utils/PluginUtils.ts b/webapp/src/components/utils/PluginUtils.ts new file mode 100644 index 000000000..65dfcd636 --- /dev/null +++ b/webapp/src/components/utils/PluginUtils.ts @@ -0,0 +1,64 @@ +import { + PluginManifest, + PluginManifestKeys, + isManifestAuthType, + isHttpAuthorizationType, + requiresUserLevelAuth +} from "../../libs/models/PluginManifest"; + +export const isValidPluginManifest = (manifest: PluginManifest) => { + const missingKeys: string[] = []; + + PluginManifestKeys.forEach((key: string) => { + if (!(key in manifest)) { + missingKeys.push(key); + } + }); + + if (missingKeys.length > 0) { + throw new Error(`Plugin manifest is missing the following keys: ${missingKeys.toLocaleString()}`); + } + + // Check that the auth type is valid + const authType = manifest.auth.type; + if (!isManifestAuthType(manifest.auth.type)) { + throw new Error(`Invalid auth type: ${authType}`); + } + + // Check that the auth properties match the auth type + if (requiresUserLevelAuth(manifest.auth)) { + if (!('authorization_type' in manifest.auth)) { + throw new Error('Missing authorization_type for user_http auth'); + } + const authHttpType = manifest.auth.authorization_type; + if (!isHttpAuthorizationType(authHttpType)) { + throw new Error(`Invalid authorization_type for user_http auth: ${authHttpType as string}`); + } + } + + // Check that the api type is valid + const apiType = manifest.api.type; + if ((apiType as unknown) !== 'openapi') { + throw new Error(`Invalid api type: ${apiType as string}. Only openapi is supported.`); + } + + // Check that the api url is valid + const apiUrl = manifest.api.url; + if (!apiUrl.startsWith('http')) { + throw new Error(`Invalid api url: ${apiUrl}. Must start with http or https.`); + } else { + try { + new URL(apiUrl); + } catch { + throw new Error(`Invalid api url: ${apiUrl}`); + } + } + + // If no errors are thrown, the plugin manifest is valid + return true; +}; + +export const isValidOpenAPISpec = (_specPath: string) => { + // TODO: [Issue #1973] Implement validation of OpenAPI spec + return true; +}; diff --git a/webapp/src/libs/hooks/index.ts b/webapp/src/libs/hooks/index.ts new file mode 100644 index 000000000..8d25f4209 --- /dev/null +++ b/webapp/src/libs/hooks/index.ts @@ -0,0 +1,4 @@ +export { useChat } from './useChat'; +export { useFile } from './useFile'; +export { useGraph } from './useGraph'; +export { usePlugins } from './usePlugins'; diff --git a/webapp/src/libs/useChat.ts b/webapp/src/libs/hooks/useChat.ts similarity index 87% rename from webapp/src/libs/useChat.ts rename to webapp/src/libs/hooks/useChat.ts index 951b027b5..a4b5706d1 100644 --- a/webapp/src/libs/useChat.ts +++ b/webapp/src/libs/hooks/useChat.ts @@ -1,34 +1,34 @@ // Copyright (c) Microsoft. All rights reserved. import { useMsal } from '@azure/msal-react'; -import { Constants } from '../Constants'; -import { useAppDispatch, useAppSelector } from '../redux/app/hooks'; -import { RootState } from '../redux/app/store'; -import { addAlert } from '../redux/features/app/appSlice'; -import { ChatState } from '../redux/features/conversations/ChatState'; -import { Conversations } from '../redux/features/conversations/ConversationsState'; +import { Constants } from '../../Constants'; +import { useAppDispatch, useAppSelector } from '../../redux/app/hooks'; +import { RootState } from '../../redux/app/store'; +import { addAlert } from '../../redux/features/app/appSlice'; +import { ChatState } from '../../redux/features/conversations/ChatState'; +import { Conversations } from '../../redux/features/conversations/ConversationsState'; import { addConversation, setConversations, setSelectedConversation, -} from '../redux/features/conversations/conversationsSlice'; -import { Plugin } from '../redux/features/plugins/PluginsState'; -import { AuthHelper } from './auth/AuthHelper'; -import { AlertType } from './models/AlertType'; -import { Bot } from './models/Bot'; -import { ChatMessageType } from './models/ChatMessage'; -import { IChatSession } from './models/ChatSession'; -import { IChatUser } from './models/ChatUser'; -import { IAskVariables } from './semantic-kernel/model/Ask'; -import { BotService } from './services/BotService'; -import { ChatService } from './services/ChatService'; -import { DocumentImportService } from './services/DocumentImportService'; - -import botIcon1 from '../assets/bot-icons/bot-icon-1.png'; -import botIcon2 from '../assets/bot-icons/bot-icon-2.png'; -import botIcon3 from '../assets/bot-icons/bot-icon-3.png'; -import botIcon4 from '../assets/bot-icons/bot-icon-4.png'; -import botIcon5 from '../assets/bot-icons/bot-icon-5.png'; +} from '../../redux/features/conversations/conversationsSlice'; +import { Plugin } from '../../redux/features/plugins/PluginsState'; +import { AuthHelper } from '../auth/AuthHelper'; +import { AlertType } from '../models/AlertType'; +import { Bot } from '../models/Bot'; +import { ChatMessageType } from '../models/ChatMessage'; +import { IChatSession } from '../models/ChatSession'; +import { IChatUser } from '../models/ChatUser'; +import { IAskVariables } from '../semantic-kernel/model/Ask'; +import { BotService } from '../services/BotService'; +import { ChatService } from '../services/ChatService'; +import { DocumentImportService } from '../services/DocumentImportService'; + +import botIcon1 from '../../assets/bot-icons/bot-icon-1.png'; +import botIcon2 from '../../assets/bot-icons/bot-icon-2.png'; +import botIcon3 from '../../assets/bot-icons/bot-icon-3.png'; +import botIcon4 from '../../assets/bot-icons/bot-icon-4.png'; +import botIcon5 from '../../assets/bot-icons/bot-icon-5.png'; export interface GetResponseOptions { messageType: ChatMessageType; @@ -61,7 +61,7 @@ export const useChat = () => { isTyping: false, }; - const plugins = useAppSelector((state: RootState) => state.plugins); + const { plugins } = useAppSelector((state: RootState) => state.plugins); const getChatUserById = (id: string, chatId: string, users: IChatUser[]) => { if (id === `${chatId}-bot` || id.toLocaleLowerCase() === 'bot') return Constants.bot.profile; diff --git a/webapp/src/libs/useFile.ts b/webapp/src/libs/hooks/useFile.ts similarity index 100% rename from webapp/src/libs/useFile.ts rename to webapp/src/libs/hooks/useFile.ts diff --git a/webapp/src/libs/useGraph.ts b/webapp/src/libs/hooks/useGraph.ts similarity index 91% rename from webapp/src/libs/useGraph.ts rename to webapp/src/libs/hooks/useGraph.ts index 6f9dfe805..168cc5052 100644 --- a/webapp/src/libs/useGraph.ts +++ b/webapp/src/libs/hooks/useGraph.ts @@ -1,13 +1,13 @@ import { useMsal } from '@azure/msal-react'; -import { Constants } from '../Constants'; -import { useAppDispatch, useAppSelector } from '../redux/app/hooks'; -import { RootState } from '../redux/app/store'; -import { addAlert } from '../redux/features/app/appSlice'; -import { UserData } from '../redux/features/users/UsersState'; -import { setUsers } from '../redux/features/users/usersSlice'; -import { TokenHelper } from './auth/TokenHelper'; -import { AlertType } from './models/AlertType'; -import { BatchRequest, BatchResponse, GraphService } from './services/GraphService'; +import { Constants } from '../../Constants'; +import { useAppSelector, useAppDispatch } from '../../redux/app/hooks'; +import { RootState } from '../../redux/app/store'; +import { addAlert } from '../../redux/features/app/appSlice'; +import { UserData } from '../../redux/features/users/UsersState'; +import { setUsers } from '../../redux/features/users/usersSlice'; +import { TokenHelper } from '../auth/TokenHelper'; +import { AlertType } from '../models/AlertType'; +import { GraphService, BatchResponse, BatchRequest } from '../services/GraphService'; export const useGraph = () => { const { instance, inProgress } = useMsal(); diff --git a/webapp/src/libs/hooks/usePlugins.ts b/webapp/src/libs/hooks/usePlugins.ts new file mode 100644 index 000000000..066fd0f01 --- /dev/null +++ b/webapp/src/libs/hooks/usePlugins.ts @@ -0,0 +1,30 @@ +import { useAppDispatch } from '../../redux/app/hooks'; +import { addPlugin } from '../../redux/features/plugins/pluginsSlice'; +import { Plugin } from '../../redux/features/plugins/PluginsState'; +import { PluginManifest, requiresUserLevelAuth } from '../models/PluginManifest'; + +export const usePlugins = () => { + const dispatch = useAppDispatch(); + + const addCustomPlugin = (manifest: PluginManifest, manifestDomain: string) => { + const newPlugin: Plugin = { + name: manifest.name_for_human, + nameForModel: manifest.name_for_model, + publisher: 'Custom Plugin', + description: manifest.description_for_human, + enabled: false, + authRequirements: { + personalAccessToken: requiresUserLevelAuth(manifest.auth), + }, + headerTag: manifest.name_for_model, + icon: manifest.logo_url, + manifestDomain: manifestDomain, + }; + + dispatch(addPlugin(newPlugin)); + }; + + return { + addCustomPlugin, + }; +}; diff --git a/webapp/src/libs/models/PluginManifest.ts b/webapp/src/libs/models/PluginManifest.ts new file mode 100644 index 000000000..5cfeb6980 --- /dev/null +++ b/webapp/src/libs/models/PluginManifest.ts @@ -0,0 +1,61 @@ +type HttpAuthorizationType = 'bearer'; +export function isHttpAuthorizationType(value: unknown): value is HttpAuthorizationType { + return value === 'bearer'; +} + +type ManifestAuthType = 'none' | 'user_http'; +export function isManifestAuthType(value: unknown): value is ManifestAuthType { + return (value as ManifestAuthType) === 'none' || value === 'user_http'; +} + +export function requiresUserLevelAuth(auth: ManifestAuth): boolean { + return auth.type === 'user_http'; +} + +interface BaseManifestAuth { + type: ManifestAuthType; + instructions?: string; +} + +interface ManifestNoAuth extends BaseManifestAuth { + type: 'none'; +} + +interface ManifestUserHttpAuth extends BaseManifestAuth { + type: 'user_http'; + authorization_type: HttpAuthorizationType; +} + +type ManifestAuth = ManifestNoAuth | ManifestUserHttpAuth; + +interface ManifestApi { + type: 'openapi'; + url: string; +} + +// Define the class for the plugin manifest +export interface PluginManifest { + schema_version: string; + name_for_model: string; + name_for_human: string; + description_for_model: string; + description_for_human: string; + auth: ManifestAuth; + api: ManifestApi; + logo_url: string; + contact_email: string; + legal_info_url: string; +} + +export const PluginManifestKeys = [ + 'schema_version', + 'name_for_model', + 'name_for_human', + 'description_for_model', + 'description_for_human', + 'auth', + 'api', + 'logo_url', + 'contact_email', + 'legal_info_url', +]; diff --git a/webapp/src/libs/semantic-kernel/model/CustomPlugin.ts b/webapp/src/libs/semantic-kernel/model/CustomPlugin.ts new file mode 100644 index 000000000..8d9857824 --- /dev/null +++ b/webapp/src/libs/semantic-kernel/model/CustomPlugin.ts @@ -0,0 +1,7 @@ +export interface ICustomPlugin { + nameForHuman: string; + nameForModel: string; + authHeaderTag: string; + authType: string; + manifestDomain: string; +} diff --git a/webapp/src/libs/services/ChatService.ts b/webapp/src/libs/services/ChatService.ts index 18fa58efa..8ab7dfff6 100644 --- a/webapp/src/libs/services/ChatService.ts +++ b/webapp/src/libs/services/ChatService.ts @@ -7,6 +7,7 @@ import { IChatParticipant } from '../models/ChatParticipant'; import { IChatSession } from '../models/ChatSession'; import { IChatUser } from '../models/ChatUser'; import { IAsk, IAskVariables } from '../semantic-kernel/model/Ask'; +import { ICustomPlugin } from '../semantic-kernel/model/CustomPlugin'; import { BaseService } from './BaseService'; export class ChatService extends BaseService { @@ -97,7 +98,23 @@ export class ChatService extends BaseService { if (enabledPlugins && enabledPlugins.length > 0) { const openApiSkillVariables: IAskVariables[] = []; + // List of custom plugins to append to context variables + const customPlugins: ICustomPlugin[] = []; + for (const plugin of enabledPlugins) { + + // If user imported a manifest domain, add custom plugin + if (plugin.manifestDomain) { + customPlugins.push({ + nameForHuman: plugin.name, + nameForModel: plugin.nameForModel as string, + authHeaderTag: plugin.headerTag, + authType: plugin.authRequirements.personalAccessToken ? 'user_http' : 'none', + manifestDomain: plugin.manifestDomain, + }); + } + + // If skill requires any additional api properties, append to context variables if (plugin.apiProperties) { const apiProperties = plugin.apiProperties; @@ -118,6 +135,13 @@ export class ChatService extends BaseService { } } + if (customPlugins.length > 0) { + openApiSkillVariables.push({ + key: `customPlugins`, + value: JSON.stringify(customPlugins), + }); + } + ask.variables = ask.variables ? ask.variables.concat(openApiSkillVariables) : openApiSkillVariables; } diff --git a/webapp/src/redux/features/plugins/PluginsState.ts b/webapp/src/redux/features/plugins/PluginsState.ts index a75ada935..52c665715 100644 --- a/webapp/src/redux/features/plugins/PluginsState.ts +++ b/webapp/src/redux/features/plugins/PluginsState.ts @@ -10,7 +10,7 @@ import GraphIcon from '../../../assets/plugin-icons/ms-graph.png'; * For each OpenAPI Spec you're supporting in the Kernel, * add all the relevant information here. */ -export const enum Plugins { +export const enum BuiltInPlugins { MsGraph = 'Microsoft Graph', Jira = 'Jira', GitHub = 'GitHub', @@ -49,92 +49,101 @@ export type AdditionalApiProperties = Record< >; export interface Plugin { - name: Plugins; + name: BuiltInPlugins | string; + nameForModel?: string; publisher: string; description: string; enabled: boolean; authRequirements: PluginAuthRequirements; - headerTag: AuthHeaderTags; + headerTag: AuthHeaderTags | string; icon: string; // Can be imported as shown above or direct URL authData?: string; // token or encoded auth header value apiProperties?: AdditionalApiProperties; + manifestDomain?: string; // Website domain hosting the OpenAI Plugin Manifest file for custom plugins } -export type PluginsState = Record; +export interface PluginsState { + plugins: Plugins; +} + +export type Plugins = Record; export const initialState: PluginsState = { - MsGraph: { - name: Plugins.MsGraph, - publisher: 'Microsoft', - description: 'Use your Microsoft Account to access your personal Graph information and Microsoft services.', - enabled: false, - authRequirements: { - Msal: true, - scopes: Constants.msGraphPluginScopes, - }, - headerTag: AuthHeaderTags.MsGraph, - icon: GraphIcon, - }, - Jira: { - name: Plugins.Jira, - publisher: 'Atlassian', - description: - 'Authorize Copilot Chat to link with Jira and retrieve specific issues by providing the issue key.', - enabled: false, - authRequirements: { - email: true, - personalAccessToken: true, - helpLink: 'https://developer.atlassian.com/cloud/confluence/basic-auth-for-rest-apis/', - }, - icon: JiraIcon, - headerTag: AuthHeaderTags.Jira, - apiProperties: { - 'jira-server-url': { - description: 'server url, i.e. "https://.atlassian.net/rest/api/latest/"', - required: true, - helpLink: 'https://confluence.atlassian.com/adminjiraserver/configuring-the-base-url-938847830.html', + plugins: { + [BuiltInPlugins.MsGraph]: { + name: BuiltInPlugins.MsGraph, + publisher: 'Microsoft', + description: 'Use your Microsoft Account to access your personal Graph information and Microsoft services.', + enabled: false, + authRequirements: { + Msal: true, + scopes: Constants.plugins.msGraphScopes, }, + headerTag: AuthHeaderTags.MsGraph, + icon: GraphIcon, }, - }, - GitHub: { - name: Plugins.GitHub, - publisher: 'Microsoft', - description: - 'Integrate Github with Copilot Chat, i.e., allow Copilot ChatBot to list active Pull Requests for you.', - enabled: false, - authRequirements: { - personalAccessToken: true, - scopes: ['Read and Write access to pull requests'], - helpLink: - 'https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token', + [BuiltInPlugins.Jira]: { + name: BuiltInPlugins.Jira, + publisher: 'Atlassian', + description: + 'Authorize Chat Copilot to link with Jira and retrieve specific issues by providing the issue key.', + enabled: false, + authRequirements: { + email: true, + personalAccessToken: true, + helpLink: 'https://developer.atlassian.com/cloud/confluence/basic-auth-for-rest-apis/', + }, + icon: JiraIcon, + headerTag: AuthHeaderTags.Jira, + apiProperties: { + 'jira-server-url': { + description: 'server url, i.e. "https://.atlassian.net/rest/api/latest/"', + required: true, + helpLink: + 'https://confluence.atlassian.com/adminjiraserver/configuring-the-base-url-938847830.html', + }, + }, }, - icon: GithubIcon, - headerTag: AuthHeaderTags.GitHub, - apiProperties: { - owner: { - required: false, - description: 'account owner of repository. i.e., "microsoft"', + [BuiltInPlugins.GitHub]: { + name: BuiltInPlugins.GitHub, + publisher: 'Microsoft', + description: + 'Integrate Github with Chat Copilot, i.e., allow Chat CopilotBot to list active Pull Requests for you.', + enabled: false, + authRequirements: { + personalAccessToken: true, + scopes: ['Read and Write access to pull requests'], + helpLink: + 'https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token', }, - repo: { - required: false, - description: 'name of repository. i.e., "semantic-kernel"', - helpLink: 'https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#list-pull-requests', + icon: GithubIcon, + headerTag: AuthHeaderTags.GitHub, + apiProperties: { + owner: { + required: false, + description: 'account owner of repository. i.e., "microsoft"', + }, + repo: { + required: false, + description: 'name of repository. i.e., "semantic-kernel"', + helpLink: 'https://docs.github.com/en/rest/pulls/pulls?apiVersion=2022-11-28#list-pull-requests', + }, }, }, - }, - Klarna: { - name: Plugins.Klarna, - publisher: 'Klarna', - description: 'Search and compare prices from thousands of online shops.', - enabled: false, - authRequirements: {}, - icon: KlarnaIcon, - headerTag: AuthHeaderTags.Klarna, + [BuiltInPlugins.Klarna]: { + name: BuiltInPlugins.Klarna, + publisher: 'Klarna', + description: 'Search and compare prices from thousands of online shops.', + enabled: false, + authRequirements: {}, + icon: KlarnaIcon, + headerTag: AuthHeaderTags.Klarna, + }, }, }; export interface EnablePluginPayload { - plugin: Plugins; + plugin: string; username?: string; email?: string; password?: string; diff --git a/webapp/src/redux/features/plugins/pluginsSlice.ts b/webapp/src/redux/features/plugins/pluginsSlice.ts index da6a50723..9f7383bf0 100644 --- a/webapp/src/redux/features/plugins/pluginsSlice.ts +++ b/webapp/src/redux/features/plugins/pluginsSlice.ts @@ -1,56 +1,49 @@ // Copyright (c) Microsoft. All rights reserved. import { createSlice, PayloadAction } from '@reduxjs/toolkit'; -import { EnablePluginPayload, initialState, Plugin, Plugins, PluginsState } from './PluginsState'; +import { BuiltInPlugins, EnablePluginPayload, initialState, Plugin, PluginsState } from './PluginsState'; export const pluginsState = createSlice({ name: 'plugins', initialState, reducers: { connectPlugin: (state: PluginsState, action: PayloadAction) => { - let plugin: Plugin; + const plugin: Plugin = state.plugins[action.payload.plugin]; let authData = action.payload.accessToken; switch (action.payload.plugin) { - case Plugins.MsGraph: - plugin = state.MsGraph; - break; - case Plugins.Jira: - plugin = state.Jira; + case BuiltInPlugins.Jira: authData = `${action.payload.email as string}:${action.payload.accessToken as string}`; break; - case Plugins.GitHub: - plugin = state.GitHub; - break; - case Plugins.Klarna: - plugin = state.Klarna; - authData = 'klarna-auth-data'; - break; + default: + // Plugins requiring no auth + if (!authData || authData === '') { + authData = `${plugin.headerTag}-auth-data`; + } } plugin.enabled = true; plugin.authData = authData; plugin.apiProperties = action.payload.apiProperties; }, - disconnectPlugin: (state: PluginsState, action: PayloadAction) => { - switch (action.payload) { - case Plugins.MsGraph: - state.MsGraph = initialState.Jira; - break; - case Plugins.Jira: - state.Jira = initialState.MsGraph; - break; - case Plugins.GitHub: - state.GitHub = initialState.GitHub; - break; - case Plugins.Klarna: - state.Klarna = initialState.Klarna; - break; + disconnectPlugin: (state: PluginsState, action: PayloadAction) => { + const plugin = state.plugins[action.payload]; + plugin.enabled = false; + plugin.authData = undefined; + const apiProperties = plugin.apiProperties; + if (apiProperties) { + Object.keys(apiProperties).forEach((key) => { + apiProperties[key].value = undefined; + }); } }, + addPlugin: (state: PluginsState, action: PayloadAction) => { + const newId = action.payload.name; + state.plugins = { ...state.plugins, [newId]: action.payload }; + }, }, }); -export const { connectPlugin, disconnectPlugin } = pluginsState.actions; +export const { connectPlugin, disconnectPlugin, addPlugin } = pluginsState.actions; export default pluginsState.reducer; diff --git a/webapp/src/styles.tsx b/webapp/src/styles.tsx index e581b079b..911ecec04 100644 --- a/webapp/src/styles.tsx +++ b/webapp/src/styles.tsx @@ -1,4 +1,13 @@ -import { BrandVariants, GriffelStyle, createLightTheme, themeToTokensObject, tokens } from '@fluentui/react-components'; +import { + BrandVariants, + GriffelStyle, + Theme, + createDarkTheme, + createLightTheme, + makeStyles, + themeToTokensObject, + tokens, +} from '@fluentui/react-components'; const semanticKernelBrandRamp: BrandVariants = { 10: '#060103', @@ -19,7 +28,15 @@ const semanticKernelBrandRamp: BrandVariants = { 160: '#EFCFD6', }; -export const semanticKernelLightTheme = createLightTheme(semanticKernelBrandRamp); +export const semanticKernelLightTheme: Theme & { colorMeBackground: string } = { + ...createLightTheme(semanticKernelBrandRamp), + colorMeBackground: '#e8ebf9', +}; + +export const semanticKernelDarkTheme: Theme & { colorMeBackground: string } = { + ...createDarkTheme(semanticKernelBrandRamp), + colorMeBackground: '#2b2b3e', +}; export const customTokens = themeToTokensObject(semanticKernelLightTheme); @@ -50,3 +67,35 @@ export const SharedStyles: Record = { ...ScrollBarStyles, }, }; + +export const useDialogClasses = makeStyles({ + root: { + height: '515px', + }, + content: { + display: 'flex', + flexDirection: 'column', + rowGap: '10px', + }, + scopes: { + display: 'flex', + flexDirection: 'column', + rowGap: '5px', + paddingLeft: '20px', + }, + error: { + color: '#d13438', + }, + section: { + display: 'flex', + flexDirection: 'column', + width: '100%', + rowGap: '10px', + }, + footer: { + display: 'flex', + flexDirection: 'column', + alignItems: 'flex-start', + minWidth: '175px', + }, +}); From 7d74103479826273b76d592fd45f9a8e94bc5738 Mon Sep 17 00:00:00 2001 From: Tao Chen Date: Wed, 26 Jul 2023 09:32:38 -0700 Subject: [PATCH 022/582] Add documents tab (#34) ### Motivation and Context Refactor files tab to documents tab. ### Description 1. Enable document import in the documents tab. 2. Show progress on each document importing. 3. Show token usage of each imported document. 4. Move alerts to the bottom of the screen. 5. 5. Add support for markdown files. ![image](https://github.com/microsoft/chat-copilot/assets/12570346/987bebd5-9f2b-4332-8c0b-15d174bc8681) ![image](https://github.com/microsoft/chat-copilot/assets/12570346/53960229-84aa-45dd-a5a5-f50c1f3999ec) ![image](https://github.com/microsoft/chat-copilot/assets/12570346/c23404f5-f3e1-499f-9ca9-4d4ecdb5fea9) ![image](https://github.com/microsoft/chat-copilot/assets/12570346/a265ff60-54a2-449f-8ae4-1f7ec53202b1) ### Contribution Checklist - [ ] The code builds clean without any errors or warnings - [ ] The PR follows the [Contribution Guidelines](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/copilot-chat/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [ ] All unit tests pass, and I have added new tests where possible - [ ] I didn't break anyone :smile: --- .../Controllers/DocumentImportController.cs | 81 +++++--- webapi/CopilotChat/Models/MemorySource.cs | 6 + webapp/src/components/chat/ChatInput.tsx | 8 +- .../src/components/chat/ChatResourceList.tsx | 182 ++++++++++++++++-- webapp/src/components/chat/ChatWindow.tsx | 62 ++---- webapp/src/components/shared/Alerts.tsx | 57 ++++++ webapp/src/libs/models/ChatMemorySource.ts | 1 + .../redux/features/conversations/ChatState.ts | 1 + .../conversations/conversationsSlice.ts | 8 + 9 files changed, 315 insertions(+), 91 deletions(-) create mode 100644 webapp/src/components/shared/Alerts.tsx diff --git a/webapi/CopilotChat/Controllers/DocumentImportController.cs b/webapi/CopilotChat/Controllers/DocumentImportController.cs index f663662fa..fd581cd5b 100644 --- a/webapi/CopilotChat/Controllers/DocumentImportController.cs +++ b/webapi/CopilotChat/Controllers/DocumentImportController.cs @@ -17,6 +17,7 @@ using SemanticKernel.Service.CopilotChat.Hubs; using SemanticKernel.Service.CopilotChat.Models; using SemanticKernel.Service.CopilotChat.Options; +using SemanticKernel.Service.CopilotChat.Skills; using SemanticKernel.Service.CopilotChat.Storage; using SemanticKernel.Service.Services; using Tesseract; @@ -47,6 +48,11 @@ private enum SupportedFileType ///
Pdf, + /// + /// .md + /// + Md, + /// /// .jpg /// @@ -184,6 +190,11 @@ private sealed class ImportResult /// public IEnumerable Keys { get; set; } = new List(); + /// + /// The number of tokens in the document. + /// + public long Tokens { get; set; } = 0; + /// /// Create a new instance of the class. /// @@ -248,15 +259,8 @@ private async Task ValidateDocumentImportFormAsync(DocumentImportForm documentIm } // Make sure the file type is supported. - var fileType = this.GetFileType(Path.GetFileName(formFile.FileName)); - switch (fileType) - { - case SupportedFileType.Txt: - case SupportedFileType.Pdf: - break; - default: - throw new ArgumentException($"Unsupported file type: {fileType}"); - } + // GetFileType throws ArgumentOutOfRangeException if the file type is not supported. + this.GetFileType(Path.GetFileName(formFile.FileName)); } } @@ -274,6 +278,7 @@ private async Task ImportDocumentHelperAsync(IKernel kernel, IForm switch (fileType) { case SupportedFileType.Txt: + case SupportedFileType.Md: documentContent = await this.ReadTxtFileAsync(formFile); break; case SupportedFileType.Pdf: @@ -295,11 +300,7 @@ private async Task ImportDocumentHelperAsync(IKernel kernel, IForm this._logger.LogInformation("Importing document {0}", formFile.FileName); // Create memory source - var memorySource = await this.TryCreateAndUpsertMemorySourceAsync(formFile, documentImportForm); - if (memorySource == null) - { - return ImportResult.Fail(); - } + var memorySource = this.CreateMemorySourceAsync(formFile, documentImportForm); // Parse document content to memory ImportResult importResult = ImportResult.Fail(); @@ -315,7 +316,15 @@ private async Task ImportDocumentHelperAsync(IKernel kernel, IForm } catch (Exception ex) when (!ex.IsCriticalException()) { - await this._sourceRepository.DeleteAsync(memorySource); + this._logger.LogDebug(ex, "Failed to parse {0} document content to memory.", formFile.FileName); + return ImportResult.Fail(); + } + + // Upsert memory source + memorySource.Tokens = importResult.Tokens; + if (!(await this.TryUpsertMemorySourceAsync(memorySource))) + { + this._logger.LogDebug("Failed to upsert memory source for file {0}.", formFile.FileName); await this.RemoveMemoriesAsync(kernel, importResult); return ImportResult.Fail(); } @@ -324,33 +333,43 @@ private async Task ImportDocumentHelperAsync(IKernel kernel, IForm } /// - /// Try to create and upsert a memory source. + /// Create a memory source. /// /// The file to be uploaded /// The document upload form that contains additional necessary info - /// A MemorySource object if successful, null otherwise - private async Task TryCreateAndUpsertMemorySourceAsync( + /// A MemorySource object. + private MemorySource CreateMemorySourceAsync( IFormFile formFile, DocumentImportForm documentImportForm) { var chatId = documentImportForm.ChatId.ToString(); var userId = documentImportForm.UserId; - var memorySource = new MemorySource( + + return new MemorySource( chatId, formFile.FileName, userId, MemorySourceType.File, formFile.Length, - null); + null + ); + } + /// + /// Try to upsert a memory source. + /// + /// The memory source to be uploaded + /// True if upsert is successful. False otherwise. + private async Task TryUpsertMemorySourceAsync(MemorySource memorySource) + { try { await this._sourceRepository.UpsertAsync(memorySource); - return memorySource; + return true; } catch (Exception ex) when (ex is ArgumentOutOfRangeException) { - return null; + return false; } } @@ -414,16 +433,17 @@ private string GetReadableByteString(long bytes) /// private SupportedFileType GetFileType(string fileName) { - string extension = Path.GetExtension(fileName); + string extension = Path.GetExtension(fileName).ToUpperInvariant(); return extension switch { - ".txt" => SupportedFileType.Txt, - ".pdf" => SupportedFileType.Pdf, - ".jpg" => SupportedFileType.Jpg, - ".jpeg" => SupportedFileType.Jpg, - ".png" => SupportedFileType.Png, - ".tif" => SupportedFileType.Tiff, - ".tiff" => SupportedFileType.Tiff, + ".TXT" => SupportedFileType.Txt, + ".MD" => SupportedFileType.Md, + ".PDF" => SupportedFileType.Pdf, + ".JPG" => SupportedFileType.Jpg, + ".JPEG" => SupportedFileType.Jpg, + ".PNG" => SupportedFileType.Png, + ".TIF" => SupportedFileType.Tiff, + ".TIFF" => SupportedFileType.Tiff, _ => throw new ArgumentOutOfRangeException($"Unsupported file type: {extension}"), }; } @@ -514,6 +534,7 @@ await kernel.Memory.SaveInformationAsync( id: key, description: $"Document: {documentName}"); importResult.AddKey(key); + importResult.Tokens += Utilities.TokenCount(paragraph); } this._logger.LogInformation( diff --git a/webapi/CopilotChat/Models/MemorySource.cs b/webapi/CopilotChat/Models/MemorySource.cs index f531d5422..2cbfcd284 100644 --- a/webapi/CopilotChat/Models/MemorySource.cs +++ b/webapi/CopilotChat/Models/MemorySource.cs @@ -69,6 +69,12 @@ public enum MemorySourceType [JsonPropertyName("size")] public long Size { get; set; } + /// + /// The number of tokens in the source. + /// + [JsonPropertyName("tokens")] + public long Tokens { get; set; } = 0; + /// /// Empty constructor for serialization. /// diff --git a/webapp/src/components/chat/ChatInput.tsx b/webapp/src/components/chat/ChatInput.tsx index e29c417d2..3abbf96ff 100644 --- a/webapp/src/components/chat/ChatInput.tsx +++ b/webapp/src/components/chat/ChatInput.tsx @@ -14,7 +14,10 @@ import { GetResponseOptions, useChat } from '../../libs/hooks/useChat'; import { useAppDispatch, useAppSelector } from '../../redux/app/hooks'; import { RootState } from '../../redux/app/store'; import { addAlert } from '../../redux/features/app/appSlice'; -import { editConversationInput, updateBotResponseStatus } from '../../redux/features/conversations/conversationsSlice'; +import { + editConversationInput, updateBotResponseStatus +} from '../../redux/features/conversations/conversationsSlice'; +import { Alerts } from '../shared/Alerts'; import { SpeechService } from './../../libs/services/SpeechService'; import { updateUserIsTyping } from './../../redux/features/conversations/conversationsSlice'; import { ChatStatus } from './ChatStatus'; @@ -173,6 +176,7 @@ export const ChatInput: React.FC = ({ isDraggingOver, onDragLeav
+