diff --git a/CHANGELOG.md b/CHANGELOG.md index 03378ff..502a53d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to the "PromptMate" extension will be documented in this fil Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. -## [Unreleased] +## [v0.1.1] + +- Confirm before running shell commands + +## [v0.1.0] + +- Add autonomous mode + +## [v0.0.1] - Initial release diff --git a/package.json b/package.json index a60cf63..1f4ee0f 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "promptmate", "displayName": "PromptMate", "description": "An extension to help you develop using GPT", - "version": "0.1.0", + "version": "0.1.1", "engines": { "vscode": "^1.76.0" }, @@ -24,9 +24,10 @@ "openai" ], "activationEvents": [], - "main": "./dist/extension.js", + "main": "./dist/extension.cjs", "publisher": "MateusZitelli", "icon": "resources/logo-small.png", + "type": "module", "contributes": { "commands": [ { @@ -101,23 +102,26 @@ "devDependencies": { "@types/glob": "^8.1.0", "@types/mocha": "^10.0.1", - "@types/node": "16.x", + "@types/node": "~16.18.23", "@types/vscode": "^1.76.0", - "@typescript-eslint/eslint-plugin": "^5.53.0", - "@typescript-eslint/parser": "^5.53.0", - "@vscode/test-electron": "^2.2.3", - "eslint": "^8.34.0", + "@typescript-eslint/eslint-plugin": "^5.58.0", + "@typescript-eslint/parser": "^5.58.0", + "@vscode/test-electron": "^2.3.0", + "eslint": "^8.38.0", "glob": "^8.1.0", "html-loader": "^4.2.0", "mocha": "^10.2.0", "ts-loader": "^9.4.2", "typescript": "^4.9.5", - "webpack": "^5.75.0", + "webpack": "^5.79.0", "webpack-cli": "^5.0.1" }, "dependencies": { - "axios": "^1.3.4", + "axios": "^0.26.1", + "cheerio": "1.0.0-rc.12", "dotenv": "^16.0.3", - "micromark": "^3.1.0" + "langchain": "^0.0.57", + "micromark": "^3.1.0", + "node-fetch": "^3.3.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 85ed617..8c8d935 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -3,74 +3,93 @@ lockfileVersion: 5.4 specifiers: '@types/glob': ^8.1.0 '@types/mocha': ^10.0.1 - '@types/node': 16.x + '@types/node': ~16.18.23 '@types/vscode': ^1.76.0 - '@typescript-eslint/eslint-plugin': ^5.53.0 - '@typescript-eslint/parser': ^5.53.0 - '@vscode/test-electron': ^2.2.3 - axios: ^1.3.4 + '@typescript-eslint/eslint-plugin': ^5.58.0 + '@typescript-eslint/parser': ^5.58.0 + '@vscode/test-electron': ^2.3.0 + axios: ^0.26.1 + cheerio: 1.0.0-rc.12 dotenv: ^16.0.3 - eslint: ^8.34.0 + eslint: ^8.38.0 glob: ^8.1.0 html-loader: ^4.2.0 + langchain: ^0.0.57 micromark: ^3.1.0 mocha: ^10.2.0 + node-fetch: ^3.3.1 ts-loader: ^9.4.2 typescript: ^4.9.5 - webpack: ^5.75.0 + webpack: ^5.79.0 webpack-cli: ^5.0.1 dependencies: - axios: 1.3.4 + axios: 0.26.1 + cheerio: 1.0.0-rc.12 dotenv: 16.0.3 + langchain: 0.0.57_riadzwtpmpkkst6cn4t72dbzma micromark: 3.1.0 + node-fetch: 3.3.1 devDependencies: '@types/glob': 8.1.0 '@types/mocha': 10.0.1 - '@types/node': 16.18.16 - '@types/vscode': 1.76.0 - '@typescript-eslint/eslint-plugin': 5.55.0_342y7v4tc7ytrrysmit6jo4wri - '@typescript-eslint/parser': 5.55.0_vgl77cfdswitgr47lm5swmv43m + '@types/node': 16.18.23 + '@types/vscode': 1.77.0 + '@typescript-eslint/eslint-plugin': 5.58.0_hzv37tkb63et4viajosjuuyxgi + '@typescript-eslint/parser': 5.58.0_ze6bmax3gcsfve3yrzu6npguhe '@vscode/test-electron': 2.3.0 - eslint: 8.36.0 + eslint: 8.38.0 glob: 8.1.0 - html-loader: 4.2.0_webpack@5.76.2 + html-loader: 4.2.0_webpack@5.79.0 mocha: 10.2.0 - ts-loader: 9.4.2_a37q6j7dwawz22saey2vgkpwqm + ts-loader: 9.4.2_odl7p537j6zjcy4b5gf5bruiye typescript: 4.9.5 - webpack: 5.76.2_webpack-cli@5.0.1 - webpack-cli: 5.0.1_webpack@5.76.2 + webpack: 5.79.0_webpack-cli@5.0.1 + webpack-cli: 5.0.1_webpack@5.79.0 packages: + /@anthropic-ai/sdk/0.4.3: + resolution: {integrity: sha512-SZrlXvjUUYT9rPmSzlTtmVk1OjVNpkCzILRluhiYwNcxXfQyvPJDi0CI6PyymygcgtqEF5EVqhKmC/PtPsNEIw==} + dependencies: + '@fortaine/fetch-event-source': 3.0.6 + cross-fetch: 3.1.5 + transitivePeerDependencies: + - encoding + dev: false + /@discoveryjs/json-ext/0.5.7: resolution: {integrity: sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==} engines: {node: '>=10.0.0'} dev: true - /@eslint-community/eslint-utils/4.3.0_eslint@8.36.0: - resolution: {integrity: sha512-v3oplH6FYCULtFuCeqyuTd9D2WKO937Dxdq+GmHOLL72TTRriLxz2VLlNfkZRsvj6PKnOPAtuT6dwrs/pA5DvA==} + /@dqbd/tiktoken/1.0.6: + resolution: {integrity: sha512-umSdeZTy/SbPPKVuZKV/XKyFPmXSN145CcM3iHjBbmhlohBJg7vaDp4cPCW+xNlWL6L2U1sp7T2BD+di2sUKdA==} + dev: false + + /@eslint-community/eslint-utils/4.4.0_eslint@8.38.0: + resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 dependencies: - eslint: 8.36.0 - eslint-visitor-keys: 3.3.0 + eslint: 8.38.0 + eslint-visitor-keys: 3.4.0 dev: true - /@eslint-community/regexpp/4.4.0: - resolution: {integrity: sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==} + /@eslint-community/regexpp/4.5.0: + resolution: {integrity: sha512-vITaYzIcNmjn5tF5uxcZ/ft7/RXGrMUIS9HalWckEOF6ESiwXKoMzAQf2UW0aVd6rnOeExTJVd5hmWXucBKGXQ==} engines: {node: ^12.0.0 || ^14.0.0 || >=16.0.0} dev: true - /@eslint/eslintrc/2.0.1: - resolution: {integrity: sha512-eFRmABvW2E5Ho6f5fHLqgena46rOj7r7OKHYfLElqcBfGFHHpjBhivyi5+jOEQuSpdc/1phIZJlbC2te+tZNIw==} + /@eslint/eslintrc/2.0.2: + resolution: {integrity: sha512-3W4f5tDUra+pA+FzgugqL2pRimUTDJWKr7BINqOpkZrC0uYI0NIc0/JFgBROCU07HR6GieA5m3/rsPIhDmCXTQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: ajv: 6.12.6 debug: 4.3.4 - espree: 9.5.0 + espree: 9.5.1 globals: 13.20.0 ignore: 5.2.4 import-fresh: 3.3.0 @@ -81,11 +100,16 @@ packages: - supports-color dev: true - /@eslint/js/8.36.0: - resolution: {integrity: sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==} + /@eslint/js/8.38.0: + resolution: {integrity: sha512-IoD2MfUnOV58ghIHCiil01PcohxjbYR/qCxsoC+xNgUwh1EY8jOOrYmu3d3a71+tJJ23uscEV4X2HJWMsPJu4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true + /@fortaine/fetch-event-source/3.0.6: + resolution: {integrity: sha512-621GAuLMvKtyZQ3IA6nlDWhV1V/7PGOTNIGLUifxt0KzM+dZIweJ6F3XvQF3QnqeNfS1N7WQ0Kil1Di/lhChEw==} + engines: {node: '>=16.15'} + dev: false + /@humanwhocodes/config-array/0.11.8: resolution: {integrity: sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==} engines: {node: '>=10.10.0'} @@ -106,13 +130,13 @@ packages: resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} dev: true - /@jridgewell/gen-mapping/0.3.2: - resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} + /@jridgewell/gen-mapping/0.3.3: + resolution: {integrity: sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==} engines: {node: '>=6.0.0'} dependencies: '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/sourcemap-codec': 1.4.15 + '@jridgewell/trace-mapping': 0.3.18 dev: true /@jridgewell/resolve-uri/3.1.0: @@ -125,19 +149,23 @@ packages: engines: {node: '>=6.0.0'} dev: true - /@jridgewell/source-map/0.3.2: - resolution: {integrity: sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==} + /@jridgewell/source-map/0.3.3: + resolution: {integrity: sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==} dependencies: - '@jridgewell/gen-mapping': 0.3.2 - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/gen-mapping': 0.3.3 + '@jridgewell/trace-mapping': 0.3.18 dev: true /@jridgewell/sourcemap-codec/1.4.14: resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} dev: true - /@jridgewell/trace-mapping/0.3.17: - resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} + /@jridgewell/sourcemap-codec/1.4.15: + resolution: {integrity: sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==} + dev: true + + /@jridgewell/trace-mapping/0.3.18: + resolution: {integrity: sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==} dependencies: '@jridgewell/resolve-uri': 3.1.0 '@jridgewell/sourcemap-codec': 1.4.14 @@ -178,26 +206,26 @@ packages: /@types/eslint-scope/3.7.4: resolution: {integrity: sha512-9K4zoImiZc3HlIp6AVUDE4CWYx22a+lhSZMYNpbjW04+YF0KWj4pJXnEMjdnFTiQibFFmElcsasJXDbdI/EPhA==} dependencies: - '@types/eslint': 8.21.2 - '@types/estree': 0.0.51 + '@types/eslint': 8.37.0 + '@types/estree': 1.0.0 dev: true - /@types/eslint/8.21.2: - resolution: {integrity: sha512-EMpxUyystd3uZVByZap1DACsMXvb82ypQnGn89e1Y0a+LYu3JJscUd/gqhRsVFDkaD2MIiWo0MT8EfXr3DGRKw==} + /@types/eslint/8.37.0: + resolution: {integrity: sha512-Piet7dG2JBuDIfohBngQ3rCt7MgO9xCO4xIMKxBThCq5PNRB91IjlJ10eJVwfoNtvTErmxLzwBZ7rHZtbOMmFQ==} dependencies: - '@types/estree': 0.0.51 + '@types/estree': 1.0.0 '@types/json-schema': 7.0.11 dev: true - /@types/estree/0.0.51: - resolution: {integrity: sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ==} + /@types/estree/1.0.0: + resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==} dev: true /@types/glob/8.1.0: resolution: {integrity: sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==} dependencies: '@types/minimatch': 5.1.2 - '@types/node': 16.18.16 + '@types/node': 16.18.23 dev: true /@types/json-schema/7.0.11: @@ -216,20 +244,24 @@ packages: resolution: {integrity: sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==} dev: false - /@types/node/16.18.16: - resolution: {integrity: sha512-ZOzvDRWp8dCVBmgnkIqYCArgdFOO9YzocZp8Ra25N/RStKiWvMOXHMz+GjSeVNe5TstaTmTWPucGJkDw0XXJWA==} + /@types/node/16.18.23: + resolution: {integrity: sha512-XAMpaw1s1+6zM+jn2tmw8MyaRDIJfXxqmIQIS0HfoGYPuf7dUWeiUKopwq13KFX9lEp1+THGtlaaYx39Nxr58g==} dev: true + /@types/retry/0.12.0: + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + dev: false + /@types/semver/7.3.13: resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} dev: true - /@types/vscode/1.76.0: - resolution: {integrity: sha512-CQcY3+Fe5hNewHnOEAVYj4dd1do/QHliXaknAEYSXx2KEHUzFibDZSKptCon+HPgK55xx20pR+PBJjf0MomnBA==} + /@types/vscode/1.77.0: + resolution: {integrity: sha512-MWFN5R7a33n8eJZJmdVlifjig3LWUNRrPeO1xemIcZ0ae0TEQuRc7G2xV0LUX78RZFECY1plYBn+dP/Acc3L0Q==} dev: true - /@typescript-eslint/eslint-plugin/5.55.0_342y7v4tc7ytrrysmit6jo4wri: - resolution: {integrity: sha512-IZGc50rtbjk+xp5YQoJvmMPmJEYoC53SiKPXyqWfv15XoD2Y5Kju6zN0DwlmaGJp1Iw33JsWJcQ7nw0lGCGjVg==} + /@typescript-eslint/eslint-plugin/5.58.0_hzv37tkb63et4viajosjuuyxgi: + resolution: {integrity: sha512-vxHvLhH0qgBd3/tW6/VccptSfc8FxPQIkmNTVLWcCOVqSBvqpnKkBTYrhcGlXfSnd78azwe+PsjYFj0X34/njA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: '@typescript-eslint/parser': ^5.0.0 @@ -239,25 +271,25 @@ packages: typescript: optional: true dependencies: - '@eslint-community/regexpp': 4.4.0 - '@typescript-eslint/parser': 5.55.0_vgl77cfdswitgr47lm5swmv43m - '@typescript-eslint/scope-manager': 5.55.0 - '@typescript-eslint/type-utils': 5.55.0_vgl77cfdswitgr47lm5swmv43m - '@typescript-eslint/utils': 5.55.0_vgl77cfdswitgr47lm5swmv43m + '@eslint-community/regexpp': 4.5.0 + '@typescript-eslint/parser': 5.58.0_ze6bmax3gcsfve3yrzu6npguhe + '@typescript-eslint/scope-manager': 5.58.0 + '@typescript-eslint/type-utils': 5.58.0_ze6bmax3gcsfve3yrzu6npguhe + '@typescript-eslint/utils': 5.58.0_ze6bmax3gcsfve3yrzu6npguhe debug: 4.3.4 - eslint: 8.36.0 + eslint: 8.38.0 grapheme-splitter: 1.0.4 ignore: 5.2.4 natural-compare-lite: 1.4.0 - semver: 7.3.8 + semver: 7.4.0 tsutils: 3.21.0_typescript@4.9.5 typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/parser/5.55.0_vgl77cfdswitgr47lm5swmv43m: - resolution: {integrity: sha512-ppvmeF7hvdhUUZWSd2EEWfzcFkjJzgNQzVST22nzg958CR+sphy8A6K7LXQZd6V75m1VKjp+J4g/PCEfSCmzhw==} + /@typescript-eslint/parser/5.58.0_ze6bmax3gcsfve3yrzu6npguhe: + resolution: {integrity: sha512-ixaM3gRtlfrKzP8N6lRhBbjTow1t6ztfBvQNGuRM8qH1bjFFXIJ35XY+FC0RRBKn3C6cT+7VW1y8tNm7DwPHDQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 @@ -266,26 +298,26 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 5.55.0 - '@typescript-eslint/types': 5.55.0 - '@typescript-eslint/typescript-estree': 5.55.0_typescript@4.9.5 + '@typescript-eslint/scope-manager': 5.58.0 + '@typescript-eslint/types': 5.58.0 + '@typescript-eslint/typescript-estree': 5.58.0_typescript@4.9.5 debug: 4.3.4 - eslint: 8.36.0 + eslint: 8.38.0 typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/scope-manager/5.55.0: - resolution: {integrity: sha512-OK+cIO1ZGhJYNCL//a3ROpsd83psf4dUJ4j7pdNVzd5DmIk+ffkuUIX2vcZQbEW/IR41DYsfJTB19tpCboxQuw==} + /@typescript-eslint/scope-manager/5.58.0: + resolution: {integrity: sha512-b+w8ypN5CFvrXWQb9Ow9T4/6LC2MikNf1viLkYTiTbkQl46CnR69w7lajz1icW0TBsYmlpg+mRzFJ4LEJ8X9NA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.55.0 - '@typescript-eslint/visitor-keys': 5.55.0 + '@typescript-eslint/types': 5.58.0 + '@typescript-eslint/visitor-keys': 5.58.0 dev: true - /@typescript-eslint/type-utils/5.55.0_vgl77cfdswitgr47lm5swmv43m: - resolution: {integrity: sha512-ObqxBgHIXj8rBNm0yh8oORFrICcJuZPZTqtAFh0oZQyr5DnAHZWfyw54RwpEEH+fD8suZaI0YxvWu5tYE/WswA==} + /@typescript-eslint/type-utils/5.58.0_ze6bmax3gcsfve3yrzu6npguhe: + resolution: {integrity: sha512-FF5vP/SKAFJ+LmR9PENql7fQVVgGDOS+dq3j+cKl9iW/9VuZC/8CFmzIP0DLKXfWKpRHawJiG70rVH+xZZbp8w==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: '*' @@ -294,23 +326,23 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 5.55.0_typescript@4.9.5 - '@typescript-eslint/utils': 5.55.0_vgl77cfdswitgr47lm5swmv43m + '@typescript-eslint/typescript-estree': 5.58.0_typescript@4.9.5 + '@typescript-eslint/utils': 5.58.0_ze6bmax3gcsfve3yrzu6npguhe debug: 4.3.4 - eslint: 8.36.0 + eslint: 8.38.0 tsutils: 3.21.0_typescript@4.9.5 typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/types/5.55.0: - resolution: {integrity: sha512-M4iRh4AG1ChrOL6Y+mETEKGeDnT7Sparn6fhZ5LtVJF1909D5O4uqK+C5NPbLmpfZ0XIIxCdwzKiijpZUOvOug==} + /@typescript-eslint/types/5.58.0: + resolution: {integrity: sha512-JYV4eITHPzVQMnHZcYJXl2ZloC7thuUHrcUmxtzvItyKPvQ50kb9QXBkgNAt90OYMqwaodQh2kHutWZl1fc+1g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /@typescript-eslint/typescript-estree/5.55.0_typescript@4.9.5: - resolution: {integrity: sha512-I7X4A9ovA8gdpWMpr7b1BN9eEbvlEtWhQvpxp/yogt48fy9Lj3iE3ild/1H3jKBBIYj5YYJmS2+9ystVhC7eaQ==} + /@typescript-eslint/typescript-estree/5.58.0_typescript@4.9.5: + resolution: {integrity: sha512-cRACvGTodA+UxnYM2uwA2KCwRL7VAzo45syNysqlMyNyjw0Z35Icc9ihPJZjIYuA5bXJYiJ2YGUB59BqlOZT1Q==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: typescript: '*' @@ -318,44 +350,44 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 5.55.0 - '@typescript-eslint/visitor-keys': 5.55.0 + '@typescript-eslint/types': 5.58.0 + '@typescript-eslint/visitor-keys': 5.58.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 - semver: 7.3.8 + semver: 7.4.0 tsutils: 3.21.0_typescript@4.9.5 typescript: 4.9.5 transitivePeerDependencies: - supports-color dev: true - /@typescript-eslint/utils/5.55.0_vgl77cfdswitgr47lm5swmv43m: - resolution: {integrity: sha512-FkW+i2pQKcpDC3AY6DU54yl8Lfl14FVGYDgBTyGKB75cCwV3KpkpTMFi9d9j2WAJ4271LR2HeC5SEWF/CZmmfw==} + /@typescript-eslint/utils/5.58.0_ze6bmax3gcsfve3yrzu6npguhe: + resolution: {integrity: sha512-gAmLOTFXMXOC+zP1fsqm3VceKSBQJNzV385Ok3+yzlavNHZoedajjS4UyS21gabJYcobuigQPs/z71A9MdJFqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 dependencies: - '@eslint-community/eslint-utils': 4.3.0_eslint@8.36.0 + '@eslint-community/eslint-utils': 4.4.0_eslint@8.38.0 '@types/json-schema': 7.0.11 '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.55.0 - '@typescript-eslint/types': 5.55.0 - '@typescript-eslint/typescript-estree': 5.55.0_typescript@4.9.5 - eslint: 8.36.0 + '@typescript-eslint/scope-manager': 5.58.0 + '@typescript-eslint/types': 5.58.0 + '@typescript-eslint/typescript-estree': 5.58.0_typescript@4.9.5 + eslint: 8.38.0 eslint-scope: 5.1.1 - semver: 7.3.8 + semver: 7.4.0 transitivePeerDependencies: - supports-color - typescript dev: true - /@typescript-eslint/visitor-keys/5.55.0: - resolution: {integrity: sha512-q2dlHHwWgirKh1D3acnuApXG+VNXpEY5/AwRxDVuEQpxWaB0jCDe0jFMVMALJ3ebSfuOVE8/rMS+9ZOYGg1GWw==} + /@typescript-eslint/visitor-keys/5.58.0: + resolution: {integrity: sha512-/fBraTlPj0jwdyTwLyrRTxv/3lnU2H96pNTVM6z3esTWLtA5MZ9ghSMJ7Rb+TtUAdtEw9EyJzJ0EydIMKxQ9gA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: - '@typescript-eslint/types': 5.55.0 - eslint-visitor-keys: 3.3.0 + '@typescript-eslint/types': 5.58.0 + eslint-visitor-keys: 3.4.0 dev: true /@vscode/test-electron/2.3.0: @@ -365,7 +397,7 @@ packages: http-proxy-agent: 4.0.1 https-proxy-agent: 5.0.1 jszip: 3.10.1 - semver: 7.3.8 + semver: 7.4.0 transitivePeerDependencies: - supports-color dev: true @@ -476,29 +508,29 @@ packages: '@xtuc/long': 4.2.2 dev: true - /@webpack-cli/configtest/2.0.1_4puitx5hps5iiy4n2enrchvjna: + /@webpack-cli/configtest/2.0.1_7fr2ry7hpnrkcoqpnojp64xaom: resolution: {integrity: sha512-njsdJXJSiS2iNbQVS0eT8A/KPnmyH4pv1APj2K0d1wrZcBLw+yppxOy4CGqa0OxDJkzfL/XELDhD8rocnIwB5A==} engines: {node: '>=14.15.0'} peerDependencies: webpack: 5.x.x webpack-cli: 5.x.x dependencies: - webpack: 5.76.2_webpack-cli@5.0.1 - webpack-cli: 5.0.1_webpack@5.76.2 + webpack: 5.79.0_webpack-cli@5.0.1 + webpack-cli: 5.0.1_webpack@5.79.0 dev: true - /@webpack-cli/info/2.0.1_4puitx5hps5iiy4n2enrchvjna: + /@webpack-cli/info/2.0.1_7fr2ry7hpnrkcoqpnojp64xaom: resolution: {integrity: sha512-fE1UEWTwsAxRhrJNikE7v4EotYflkEhBL7EbajfkPlf6E37/2QshOy/D48Mw8G5XMFlQtS6YV42vtbG9zBpIQA==} engines: {node: '>=14.15.0'} peerDependencies: webpack: 5.x.x webpack-cli: 5.x.x dependencies: - webpack: 5.76.2_webpack-cli@5.0.1 - webpack-cli: 5.0.1_webpack@5.76.2 + webpack: 5.79.0_webpack-cli@5.0.1 + webpack-cli: 5.0.1_webpack@5.79.0 dev: true - /@webpack-cli/serve/2.0.1_4puitx5hps5iiy4n2enrchvjna: + /@webpack-cli/serve/2.0.1_7fr2ry7hpnrkcoqpnojp64xaom: resolution: {integrity: sha512-0G7tNyS+yW8TdgHwZKlDWYXFA6OJQnoLCQvYKkQP0Q2X205PSQ6RNUj0M+1OB/9gRQaUZ/ccYfaxd0nhaWKfjw==} engines: {node: '>=14.15.0'} peerDependencies: @@ -509,8 +541,8 @@ packages: webpack-dev-server: optional: true dependencies: - webpack: 5.76.2_webpack-cli@5.0.1 - webpack-cli: 5.0.1_webpack@5.76.2 + webpack: 5.79.0_webpack-cli@5.0.1 + webpack-cli: 5.0.1_webpack@5.79.0 dev: true /@xtuc/ieee754/1.2.0: @@ -607,12 +639,10 @@ packages: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} dev: false - /axios/1.3.4: - resolution: {integrity: sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ==} + /axios/0.26.1: + resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} dependencies: follow-redirects: 1.15.2 - form-data: 4.0.0 - proxy-from-env: 1.1.0 transitivePeerDependencies: - debug dev: false @@ -624,7 +654,14 @@ packages: /binary-extensions/2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} - dev: true + + /binary-search/1.3.6: + resolution: {integrity: sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA==} + dev: false + + /boolbase/1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + dev: false /brace-expansion/1.1.11: resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} @@ -646,6 +683,10 @@ packages: fill-range: 7.0.1 dev: true + /browser-or-node/2.1.1: + resolution: {integrity: sha512-8CVjaLJGuSKMVTxJ2DpBl5XnlNDiT4cQFeuCJJrvJmts9YrTZDizTX7PjC2s6W4x+MBGZeEY6dGMrF04/6Hgqg==} + dev: false + /browser-stdout/1.3.1: resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} dev: true @@ -655,8 +696,8 @@ packages: engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} hasBin: true dependencies: - caniuse-lite: 1.0.30001467 - electron-to-chromium: 1.4.333 + caniuse-lite: 1.0.30001478 + electron-to-chromium: 1.4.365 node-releases: 2.0.10 update-browserslist-db: 1.0.10_browserslist@4.21.5 dev: true @@ -682,8 +723,8 @@ packages: engines: {node: '>=10'} dev: true - /caniuse-lite/1.0.30001467: - resolution: {integrity: sha512-cEdN/5e+RPikvl9AHm4uuLXxeCNq8rFsQ+lPHTfe/OtypP3WwnVVbjn+6uBV7PaFL6xUFzTh+sSCOz1rKhcO+Q==} + /caniuse-lite/1.0.30001478: + resolution: {integrity: sha512-gMhDyXGItTHipJj2ApIvR+iVB5hd0KP3svMWWXDvZOmjzJJassGLMfxRkQCSYgGd2gtdL/ReeiyvMSFD1Ss6Mw==} dev: true /chalk/4.1.2: @@ -698,6 +739,30 @@ packages: resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==} dev: false + /cheerio-select/2.1.0: + resolution: {integrity: sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==} + dependencies: + boolbase: 1.0.0 + css-select: 5.1.0 + css-what: 6.1.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.0.1 + dev: false + + /cheerio/1.0.0-rc.12: + resolution: {integrity: sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==} + engines: {node: '>= 6'} + dependencies: + cheerio-select: 2.1.0 + dom-serializer: 2.0.0 + domhandler: 5.0.3 + domutils: 3.0.1 + htmlparser2: 8.0.2 + parse5: 7.1.2 + parse5-htmlparser2-tree-adapter: 7.0.0 + dev: false + /chokidar/3.5.3: resolution: {integrity: sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==} engines: {node: '>= 8.10.0'} @@ -718,8 +783,8 @@ packages: engines: {node: '>=6.0'} dev: true - /clean-css/5.2.0: - resolution: {integrity: sha512-2639sWGa43EMmG7fn8mdVuBSs6HuWaSor+ZPoFWzenBc6oN+td8YhTfghWXZ25G1NiiSvz8bOFBS7PdSbTiqEA==} + /clean-css/5.3.2: + resolution: {integrity: sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww==} engines: {node: '>= 10.0'} dependencies: source-map: 0.6.1 @@ -764,6 +829,11 @@ packages: delayed-stream: 1.0.0 dev: false + /commander/10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + dev: true + /commander/2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} dev: true @@ -781,6 +851,14 @@ packages: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} dev: true + /cross-fetch/3.1.5: + resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==} + dependencies: + node-fetch: 2.6.7 + transitivePeerDependencies: + - encoding + dev: false + /cross-spawn/7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -790,6 +868,26 @@ packages: which: 2.0.2 dev: true + /css-select/5.1.0: + resolution: {integrity: sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==} + dependencies: + boolbase: 1.0.0 + css-what: 6.1.0 + domhandler: 5.0.3 + domutils: 3.0.1 + nth-check: 2.1.1 + dev: false + + /css-what/6.1.0: + resolution: {integrity: sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==} + engines: {node: '>= 6'} + dev: false + + /data-uri-to-buffer/4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + dev: false + /debug/4.3.4: resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} @@ -842,6 +940,12 @@ packages: /diff/5.0.0: resolution: {integrity: sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==} engines: {node: '>=0.3.1'} + dev: true + + /diff/5.1.0: + resolution: {integrity: sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==} + engines: {node: '>=0.3.1'} + dev: false /dir-glob/3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} @@ -857,6 +961,33 @@ packages: esutils: 2.0.3 dev: true + /dom-serializer/2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + dev: false + + /domelementtype/2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + dev: false + + /domhandler/5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + dependencies: + domelementtype: 2.3.0 + dev: false + + /domutils/3.0.1: + resolution: {integrity: sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==} + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + dev: false + /dot-case/3.0.4: resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} dependencies: @@ -869,8 +1000,8 @@ packages: engines: {node: '>=12'} dev: false - /electron-to-chromium/1.4.333: - resolution: {integrity: sha512-YyE8+GKyGtPEP1/kpvqsdhD6rA/TP1DUFDN4uiU/YI52NzDxmwHkEb3qjId8hLBa5siJvG0sfC3O66501jMruQ==} + /electron-to-chromium/1.4.365: + resolution: {integrity: sha512-FRHZO+1tUNO4TOPXmlxetkoaIY8uwHzd1kKopK/Gx2SKn1L47wJXWD44wxP5CGRyyP98z/c8e1eBzJrgPeiBOg==} dev: true /emoji-regex/8.0.0: @@ -885,10 +1016,9 @@ packages: tapable: 2.2.1 dev: true - /entities/4.4.0: - resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} + /entities/4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} - dev: true /envinfo/7.8.1: resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==} @@ -896,8 +1026,8 @@ packages: hasBin: true dev: true - /es-module-lexer/0.9.3: - resolution: {integrity: sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==} + /es-module-lexer/1.2.1: + resolution: {integrity: sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==} dev: true /escalade/3.1.1: @@ -918,28 +1048,28 @@ packages: estraverse: 4.3.0 dev: true - /eslint-scope/7.1.1: - resolution: {integrity: sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==} + /eslint-scope/7.2.0: + resolution: {integrity: sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: esrecurse: 4.3.0 estraverse: 5.3.0 dev: true - /eslint-visitor-keys/3.3.0: - resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} + /eslint-visitor-keys/3.4.0: + resolution: {integrity: sha512-HPpKPUBQcAsZOsHAFwTtIKcYlCje62XB7SEAcxjtmW6TD1WVpkS6i6/hOVtTZIl4zGj/mBqpFVGvaDneik+VoQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dev: true - /eslint/8.36.0: - resolution: {integrity: sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==} + /eslint/8.38.0: + resolution: {integrity: sha512-pIdsD2jwlUGf/U38Jv97t8lq6HpaU/G9NKbYmpWpZGw3LdTNhZLbJePqxOXGB5+JEKfOPU/XLxYxFh03nr1KTg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} hasBin: true dependencies: - '@eslint-community/eslint-utils': 4.3.0_eslint@8.36.0 - '@eslint-community/regexpp': 4.4.0 - '@eslint/eslintrc': 2.0.1 - '@eslint/js': 8.36.0 + '@eslint-community/eslint-utils': 4.4.0_eslint@8.38.0 + '@eslint-community/regexpp': 4.5.0 + '@eslint/eslintrc': 2.0.2 + '@eslint/js': 8.38.0 '@humanwhocodes/config-array': 0.11.8 '@humanwhocodes/module-importer': 1.0.1 '@nodelib/fs.walk': 1.2.8 @@ -949,9 +1079,9 @@ packages: debug: 4.3.4 doctrine: 3.0.0 escape-string-regexp: 4.0.0 - eslint-scope: 7.1.1 - eslint-visitor-keys: 3.3.0 - espree: 9.5.0 + eslint-scope: 7.2.0 + eslint-visitor-keys: 3.4.0 + espree: 9.5.1 esquery: 1.5.0 esutils: 2.0.3 fast-deep-equal: 3.1.3 @@ -965,7 +1095,7 @@ packages: imurmurhash: 0.1.4 is-glob: 4.0.3 is-path-inside: 3.0.3 - js-sdsl: 4.3.0 + js-sdsl: 4.4.0 js-yaml: 4.1.0 json-stable-stringify-without-jsonify: 1.0.1 levn: 0.4.1 @@ -980,13 +1110,13 @@ packages: - supports-color dev: true - /espree/9.5.0: - resolution: {integrity: sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==} + /espree/9.5.1: + resolution: {integrity: sha512-5yxtHSZXRSW5pvv3hAlXM5+/Oswi1AUFqBmbibKb5s6bp3rGIDkyXU6xCoyuuLhijr4SFwPrXRoZjz0AZDN9tg==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} dependencies: acorn: 8.8.2 acorn-jsx: 5.3.2_acorn@8.8.2 - eslint-visitor-keys: 3.3.0 + eslint-visitor-keys: 3.4.0 dev: true /esquery/1.5.0: @@ -1018,11 +1148,19 @@ packages: engines: {node: '>=0.10.0'} dev: true + /eventemitter3/4.0.7: + resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} + dev: false + /events/3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} dev: true + /expr-eval/2.0.2: + resolution: {integrity: sha512-4EMSHGOPSwAfBiibw3ndnP0AvjDWLsMvGOvWEZ2F96IGk0bIVdjQisOHxReSkE13mHcfbuCiXw+G4y0zv6N8Eg==} + dev: false + /fast-deep-equal/3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true @@ -1057,6 +1195,14 @@ packages: reusify: 1.0.4 dev: true + /fetch-blob/3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.2.1 + dev: false + /file-entry-cache/6.0.1: resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} engines: {node: ^10.12.0 || >=12.0.0} @@ -1098,7 +1244,6 @@ packages: /flat/5.0.2: resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} hasBin: true - dev: true /flatted/3.2.7: resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} @@ -1123,6 +1268,13 @@ packages: mime-types: 2.1.35 dev: false + /formdata-polyfill/4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + dependencies: + fetch-blob: 3.2.0 + dev: false + /fs.realpath/1.0.0: resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} dev: true @@ -1228,31 +1380,40 @@ packages: hasBin: true dev: true - /html-loader/4.2.0_webpack@5.76.2: + /html-loader/4.2.0_webpack@5.79.0: resolution: {integrity: sha512-OxCHD3yt+qwqng2vvcaPApCEvbx+nXWu+v69TYHx1FO8bffHn/JjHtE3TTQZmHjwvnJe4xxzuecetDVBrQR1Zg==} engines: {node: '>= 14.15.0'} peerDependencies: webpack: ^5.0.0 dependencies: - html-minifier-terser: 7.1.0 + html-minifier-terser: 7.2.0 parse5: 7.1.2 - webpack: 5.76.2_webpack-cli@5.0.1 + webpack: 5.79.0_webpack-cli@5.0.1 dev: true - /html-minifier-terser/7.1.0: - resolution: {integrity: sha512-BvPO2S7Ip0Q5qt+Y8j/27Vclj6uHC6av0TMoDn7/bJPhMWHI2UtR2e/zEgJn3/qYAmxumrGp9q4UHurL6mtW9Q==} + /html-minifier-terser/7.2.0: + resolution: {integrity: sha512-tXgn3QfqPIpGl9o+K5tpcj3/MN4SfLtsx2GWwBC3SSd0tXQGyF3gsSqad8loJgKZGM3ZxbYDd5yhiBIdWpmvLA==} engines: {node: ^14.13.1 || >=16.0.0} hasBin: true dependencies: camel-case: 4.1.2 - clean-css: 5.2.0 - commander: 9.5.0 - entities: 4.4.0 + clean-css: 5.3.2 + commander: 10.0.1 + entities: 4.5.0 param-case: 3.0.4 relateurl: 0.2.7 - terser: 5.16.6 + terser: 5.16.9 dev: true + /htmlparser2/8.0.2: + resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==} + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + domutils: 3.0.1 + entities: 4.5.0 + dev: false + /http-proxy-agent/4.0.1: resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} engines: {node: '>= 6'} @@ -1321,6 +1482,10 @@ packages: engines: {node: '>=10.13.0'} dev: true + /is-any-array/2.0.0: + resolution: {integrity: sha512-WdPV58rT3aOWXvvyuBydnCq4S2BM1Yz8shKxlEpk/6x+GX202XRvXOycEFtNgnHVLoc46hpexPFx8Pz1/sMS0w==} + dev: false + /is-binary-path/2.1.0: resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==} engines: {node: '>=8'} @@ -1328,8 +1493,8 @@ packages: binary-extensions: 2.2.0 dev: true - /is-core-module/2.11.0: - resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} + /is-core-module/2.12.0: + resolution: {integrity: sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==} dependencies: has: 1.0.3 dev: true @@ -1395,13 +1560,13 @@ packages: resolution: {integrity: sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==} engines: {node: '>= 10.13.0'} dependencies: - '@types/node': 16.18.16 + '@types/node': 16.18.23 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true - /js-sdsl/4.3.0: - resolution: {integrity: sha512-mifzlm2+5nZ+lEcLJMoBK0/IH/bDg8XnJfd/Wq6IP+xoCjLZsTOnV2QpxlVbX9bMnkl5PdEjNtBJ9Cj1NjifhQ==} + /js-sdsl/4.4.0: + resolution: {integrity: sha512-FfVSdx6pJ41Oa+CF7RDaFmTnCaFhua+SNYQX74riGOpl96x+2jQCqEfQ2bnXu/5DPCqlRuiqyvTJM0Qjz26IVg==} dev: true /js-yaml/4.1.0: @@ -1423,6 +1588,11 @@ packages: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} dev: true + /jsonpointer/5.0.1: + resolution: {integrity: sha512-p/nXbhSEcu3pZRdkW1OfJhpsVtW1gd4Wa1fnQc9YLiTfAjn0312eMKimbdIQzuZl9aa9xUGaRlP9T/CJE/ditQ==} + engines: {node: '>=0.10.0'} + dev: false + /jszip/3.10.1: resolution: {integrity: sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==} dependencies: @@ -1442,6 +1612,112 @@ packages: engines: {node: '>=6'} dev: false + /langchain/0.0.57_riadzwtpmpkkst6cn4t72dbzma: + resolution: {integrity: sha512-Ik8SGMzl6woXkqmdWnNIqY7ds3+y1b6FLYDhCXpTT3fHHD+vsNgiapAAdJ/lkThnYQ0y0i3gtv1pHbjfsYS5qw==} + engines: {node: '>=18'} + peerDependencies: + '@aws-sdk/client-lambda': ^3.310.0 + '@aws-sdk/client-s3': ^3.310.0 + '@getmetal/metal-sdk': '*' + '@huggingface/inference': ^1.5.1 + '@opensearch-project/opensearch': '*' + '@pinecone-database/pinecone': '*' + '@supabase/supabase-js': ^2.10.0 + '@zilliz/milvus2-sdk-node': ^2.2.0 + axios: ^0.26.0 + cheerio: ^1.0.0-rc.12 + chromadb: ^1.3.0 + cohere-ai: ^5.0.2 + d3-dsv: ^2.0.0 + epub2: ^3.0.1 + hnswlib-node: ^1.4.2 + html-to-text: ^9.0.5 + mammoth: '*' + mongodb: ^5.2.0 + pdfjs-dist: ^3.4.120 + playwright: ^1.32.1 + puppeteer: ^19.7.2 + redis: ^4.6.4 + replicate: ^0.9.0 + srt-parser-2: ^1.2.2 + typeorm: ^0.3.12 + weaviate-ts-client: ^1.0.0 + peerDependenciesMeta: + '@aws-sdk/client-lambda': + optional: true + '@aws-sdk/client-s3': + optional: true + '@getmetal/metal-sdk': + optional: true + '@huggingface/inference': + optional: true + '@opensearch-project/opensearch': + optional: true + '@pinecone-database/pinecone': + optional: true + '@supabase/supabase-js': + optional: true + '@zilliz/milvus2-sdk-node': + optional: true + axios: + optional: true + cheerio: + optional: true + chromadb: + optional: true + cohere-ai: + optional: true + d3-dsv: + optional: true + epub2: + optional: true + hnswlib-node: + optional: true + html-to-text: + optional: true + mammoth: + optional: true + mongodb: + optional: true + pdfjs-dist: + optional: true + playwright: + optional: true + puppeteer: + optional: true + redis: + optional: true + replicate: + optional: true + srt-parser-2: + optional: true + typeorm: + optional: true + weaviate-ts-client: + optional: true + dependencies: + '@anthropic-ai/sdk': 0.4.3 + '@dqbd/tiktoken': 1.0.6 + axios: 0.26.1 + binary-extensions: 2.2.0 + browser-or-node: 2.1.1 + cheerio: 1.0.0-rc.12 + expr-eval: 2.0.2 + flat: 5.0.2 + jsonpointer: 5.0.1 + ml-distance: 4.0.0 + object-hash: 3.0.0 + openai: 3.2.1 + p-queue: 6.6.2 + p-retry: 4.6.2 + uuid: 9.0.0 + yaml: 2.2.1 + zod: 3.21.4 + transitivePeerDependencies: + - debug + - encoding + dev: false + /levn/0.4.1: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} @@ -1714,6 +1990,37 @@ packages: brace-expansion: 2.0.1 dev: true + /ml-array-mean/1.1.6: + resolution: {integrity: sha512-MIdf7Zc8HznwIisyiJGRH9tRigg3Yf4FldW8DxKxpCCv/g5CafTw0RRu51nojVEOXuCQC7DRVVu5c7XXO/5joQ==} + dependencies: + ml-array-sum: 1.1.6 + dev: false + + /ml-array-sum/1.1.6: + resolution: {integrity: sha512-29mAh2GwH7ZmiRnup4UyibQZB9+ZLyMShvt4cH4eTK+cL2oEMIZFnSyB3SS8MlsTh6q/w/yh48KmqLxmovN4Dw==} + dependencies: + is-any-array: 2.0.0 + dev: false + + /ml-distance-euclidean/2.0.0: + resolution: {integrity: sha512-yC9/2o8QF0A3m/0IXqCTXCzz2pNEzvmcE/9HFKOZGnTjatvBbsn4lWYJkxENkA4Ug2fnYl7PXQxnPi21sgMy/Q==} + dev: false + + /ml-distance/4.0.0: + resolution: {integrity: sha512-zj7+UGZpHk3uL7n79XTfGNUjIGnhLn8xVvrxYvBHvXFxo3jq1q+/UjP311hZxnLVhbxbXCjUniThX8gozjacYA==} + dependencies: + ml-array-mean: 1.1.6 + ml-distance-euclidean: 2.0.0 + ml-tree-similarity: 1.0.0 + dev: false + + /ml-tree-similarity/1.0.0: + resolution: {integrity: sha512-XJUyYqjSuUQkNQHMscr6tcjldsOoAekxADTplt40QKfwW6nd++1wHWV9AArl0Zvw/TIHgNaZZNvr8QGvE8wLRg==} + dependencies: + binary-search: 1.3.6 + num-sort: 2.1.0 + dev: false + /mocha/10.2.0: resolution: {integrity: sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg==} engines: {node: '>= 14.0.0'} @@ -1779,6 +2086,32 @@ packages: tslib: 2.5.0 dev: true + /node-domexception/1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + dev: false + + /node-fetch/2.6.7: + resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} + engines: {node: 4.x || >=6.0.0} + peerDependencies: + encoding: ^0.1.0 + peerDependenciesMeta: + encoding: + optional: true + dependencies: + whatwg-url: 5.0.0 + dev: false + + /node-fetch/3.3.1: + resolution: {integrity: sha512-cRVc/kyto/7E5shrWca1Wsea4y6tL9iYJE5FBCius3JQfb/4P4I295PfhgbJQBLTx6lATE4z+wK0rPM4VS2uow==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + dev: false + /node-releases/2.0.10: resolution: {integrity: sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==} dev: true @@ -1788,12 +2121,37 @@ packages: engines: {node: '>=0.10.0'} dev: true + /nth-check/2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + dependencies: + boolbase: 1.0.0 + dev: false + + /num-sort/2.1.0: + resolution: {integrity: sha512-1MQz1Ed8z2yckoBeSfkQHHO9K1yDRxxtotKSJ9yvcTUUxSvfvzEq5GwBrjjHEpMlq/k5gvXdmJ1SbYxWtpNoVg==} + engines: {node: '>=8'} + dev: false + + /object-hash/3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} + engines: {node: '>= 6'} + dev: false + /once/1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} dependencies: wrappy: 1.0.2 dev: true + /openai/3.2.1: + resolution: {integrity: sha512-762C9BNlJPbjjlWZi4WYK9iM2tAVAv0uUp1UmI34vb0CN5T2mjB/qM6RYBmNKMh/dN9fC+bxqPwWJZUTWW052A==} + dependencies: + axios: 0.26.1 + form-data: 4.0.0 + transitivePeerDependencies: + - debug + dev: false + /optionator/0.9.1: resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} engines: {node: '>= 0.8.0'} @@ -1806,6 +2164,11 @@ packages: word-wrap: 1.2.3 dev: true + /p-finally/1.0.0: + resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} + engines: {node: '>=4'} + dev: false + /p-limit/2.3.0: resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} engines: {node: '>=6'} @@ -1834,6 +2197,29 @@ packages: p-limit: 3.1.0 dev: true + /p-queue/6.6.2: + resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} + engines: {node: '>=8'} + dependencies: + eventemitter3: 4.0.7 + p-timeout: 3.2.0 + dev: false + + /p-retry/4.6.2: + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} + engines: {node: '>=8'} + dependencies: + '@types/retry': 0.12.0 + retry: 0.13.1 + dev: false + + /p-timeout/3.2.0: + resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} + engines: {node: '>=8'} + dependencies: + p-finally: 1.0.0 + dev: false + /p-try/2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} @@ -1857,11 +2243,17 @@ packages: callsites: 3.1.0 dev: true + /parse5-htmlparser2-tree-adapter/7.0.0: + resolution: {integrity: sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==} + dependencies: + domhandler: 5.0.3 + parse5: 7.1.2 + dev: false + /parse5/7.1.2: resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==} dependencies: - entities: 4.4.0 - dev: true + entities: 4.5.0 /pascal-case/3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} @@ -1919,10 +2311,6 @@ packages: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} dev: true - /proxy-from-env/1.1.0: - resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} - dev: false - /punycode/2.3.0: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} @@ -1961,7 +2349,7 @@ packages: resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} engines: {node: '>= 10.13.0'} dependencies: - resolve: 1.22.1 + resolve: 1.22.3 dev: true /relateurl/0.2.7: @@ -1991,15 +2379,20 @@ packages: engines: {node: '>=8'} dev: true - /resolve/1.22.1: - resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} + /resolve/1.22.3: + resolution: {integrity: sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==} hasBin: true dependencies: - is-core-module: 2.11.0 + is-core-module: 2.12.0 path-parse: 1.0.7 supports-preserve-symlinks-flag: 1.0.0 dev: true + /retry/0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + dev: false + /reusify/1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2033,8 +2426,8 @@ packages: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} dev: true - /schema-utils/3.1.1: - resolution: {integrity: sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==} + /schema-utils/3.1.2: + resolution: {integrity: sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==} engines: {node: '>= 10.13.0'} dependencies: '@types/json-schema': 7.0.11 @@ -2042,8 +2435,8 @@ packages: ajv-keywords: 3.5.2_ajv@6.12.6 dev: true - /semver/7.3.8: - resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} + /semver/7.4.0: + resolution: {integrity: sha512-RgOxM8Mw+7Zus0+zcLEUn8+JfoLpj/huFTItQy2hsM4khuC1HYRDp0cU482Ewn/Fcy6bCjufD8vAj7voC66KQw==} engines: {node: '>=10'} hasBin: true dependencies: @@ -2153,7 +2546,7 @@ packages: engines: {node: '>=6'} dev: true - /terser-webpack-plugin/5.3.7_webpack@5.76.2: + /terser-webpack-plugin/5.3.7_webpack@5.79.0: resolution: {integrity: sha512-AfKwIktyP7Cu50xNjXF/6Qb5lBNzYaWpU6YfoX3uZicTx0zTy0stDDCsvjDapKsSDvOeWo5MEq4TmdBy2cNoHw==} engines: {node: '>= 10.13.0'} peerDependencies: @@ -2169,20 +2562,20 @@ packages: uglify-js: optional: true dependencies: - '@jridgewell/trace-mapping': 0.3.17 + '@jridgewell/trace-mapping': 0.3.18 jest-worker: 27.5.1 - schema-utils: 3.1.1 + schema-utils: 3.1.2 serialize-javascript: 6.0.1 - terser: 5.16.6 - webpack: 5.76.2_webpack-cli@5.0.1 + terser: 5.16.9 + webpack: 5.79.0_webpack-cli@5.0.1 dev: true - /terser/5.16.6: - resolution: {integrity: sha512-IBZ+ZQIA9sMaXmRZCUMDjNH0D5AQQfdn4WUjHL0+1lF4TP1IHRJbrhb6fNaXWikrYQTSkb7SLxkeXAiy1p7mbg==} + /terser/5.16.9: + resolution: {integrity: sha512-HPa/FdTB9XGI2H1/keLFZHxl6WNvAI4YalHGtDQTlMnJcoqSab1UwL4l1hGEhs6/GmLHBZIg/YgB++jcbzoOEg==} engines: {node: '>=10'} hasBin: true dependencies: - '@jridgewell/source-map': 0.3.2 + '@jridgewell/source-map': 0.3.3 acorn: 8.8.2 commander: 2.20.3 source-map-support: 0.5.21 @@ -2199,7 +2592,11 @@ packages: is-number: 7.0.0 dev: true - /ts-loader/9.4.2_a37q6j7dwawz22saey2vgkpwqm: + /tr46/0.0.3: + resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} + dev: false + + /ts-loader/9.4.2_odl7p537j6zjcy4b5gf5bruiye: resolution: {integrity: sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA==} engines: {node: '>=12.0.0'} peerDependencies: @@ -2209,9 +2606,9 @@ packages: chalk: 4.1.2 enhanced-resolve: 5.12.0 micromatch: 4.0.5 - semver: 7.3.8 + semver: 7.4.0 typescript: 4.9.5 - webpack: 5.76.2_webpack-cli@5.0.1 + webpack: 5.79.0_webpack-cli@5.0.1 dev: true /tslib/1.14.1: @@ -2271,13 +2668,18 @@ packages: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} dev: true + /uuid/9.0.0: + resolution: {integrity: sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==} + hasBin: true + dev: false + /uvu/0.5.6: resolution: {integrity: sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==} engines: {node: '>=8'} hasBin: true dependencies: dequal: 2.0.3 - diff: 5.0.0 + diff: 5.1.0 kleur: 4.1.5 sade: 1.8.1 dev: false @@ -2290,7 +2692,16 @@ packages: graceful-fs: 4.2.11 dev: true - /webpack-cli/5.0.1_webpack@5.76.2: + /web-streams-polyfill/3.2.1: + resolution: {integrity: sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q==} + engines: {node: '>= 8'} + dev: false + + /webidl-conversions/3.0.1: + resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} + dev: false + + /webpack-cli/5.0.1_webpack@5.79.0: resolution: {integrity: sha512-S3KVAyfwUqr0Mo/ur3NzIp6jnerNpo7GUO6so51mxLi1spqsA17YcMXy0WOIJtBSnj748lthxC6XLbNKh/ZC+A==} engines: {node: '>=14.15.0'} hasBin: true @@ -2308,9 +2719,9 @@ packages: optional: true dependencies: '@discoveryjs/json-ext': 0.5.7 - '@webpack-cli/configtest': 2.0.1_4puitx5hps5iiy4n2enrchvjna - '@webpack-cli/info': 2.0.1_4puitx5hps5iiy4n2enrchvjna - '@webpack-cli/serve': 2.0.1_4puitx5hps5iiy4n2enrchvjna + '@webpack-cli/configtest': 2.0.1_7fr2ry7hpnrkcoqpnojp64xaom + '@webpack-cli/info': 2.0.1_7fr2ry7hpnrkcoqpnojp64xaom + '@webpack-cli/serve': 2.0.1_7fr2ry7hpnrkcoqpnojp64xaom colorette: 2.0.19 commander: 9.5.0 cross-spawn: 7.0.3 @@ -2319,7 +2730,7 @@ packages: import-local: 3.1.0 interpret: 3.1.1 rechoir: 0.8.0 - webpack: 5.76.2_webpack-cli@5.0.1 + webpack: 5.79.0_webpack-cli@5.0.1 webpack-merge: 5.8.0 dev: true @@ -2336,8 +2747,8 @@ packages: engines: {node: '>=10.13.0'} dev: true - /webpack/5.76.2_webpack-cli@5.0.1: - resolution: {integrity: sha512-Th05ggRm23rVzEOlX8y67NkYCHa9nTNcwHPBhdg+lKG+mtiW7XgggjAeeLnADAe7mLjJ6LUNfgHAuRRh+Z6J7w==} + /webpack/5.79.0_webpack-cli@5.0.1: + resolution: {integrity: sha512-3mN4rR2Xq+INd6NnYuL9RC9GAmc1ROPKJoHhrZ4pAjdMFEkJJWrsPw8o2JjCIyQyTu7rTXYn4VG6OpyB3CobZg==} engines: {node: '>=10.13.0'} hasBin: true peerDependencies: @@ -2347,7 +2758,7 @@ packages: optional: true dependencies: '@types/eslint-scope': 3.7.4 - '@types/estree': 0.0.51 + '@types/estree': 1.0.0 '@webassemblyjs/ast': 1.11.1 '@webassemblyjs/wasm-edit': 1.11.1 '@webassemblyjs/wasm-parser': 1.11.1 @@ -2356,7 +2767,7 @@ packages: browserslist: 4.21.5 chrome-trace-event: 1.0.3 enhanced-resolve: 5.12.0 - es-module-lexer: 0.9.3 + es-module-lexer: 1.2.1 eslint-scope: 5.1.1 events: 3.3.0 glob-to-regexp: 0.4.1 @@ -2365,11 +2776,11 @@ packages: loader-runner: 4.3.0 mime-types: 2.1.35 neo-async: 2.6.2 - schema-utils: 3.1.1 + schema-utils: 3.1.2 tapable: 2.2.1 - terser-webpack-plugin: 5.3.7_webpack@5.76.2 + terser-webpack-plugin: 5.3.7_webpack@5.79.0 watchpack: 2.4.0 - webpack-cli: 5.0.1_webpack@5.76.2 + webpack-cli: 5.0.1_webpack@5.79.0 webpack-sources: 3.2.3 transitivePeerDependencies: - '@swc/core' @@ -2377,6 +2788,13 @@ packages: - uglify-js dev: true + /whatwg-url/5.0.0: + resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} + dependencies: + tr46: 0.0.3 + webidl-conversions: 3.0.1 + dev: false + /which/2.0.2: resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} engines: {node: '>= 8'} @@ -2420,6 +2838,11 @@ packages: resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} dev: true + /yaml/2.2.1: + resolution: {integrity: sha512-e0WHiYql7+9wr4cWMx3TVQrNwejKaEe7/rHNmQmqRjazfOP5W8PB6Jpebb5o6fIapbz9o9+2ipcaTM2ZwDI6lw==} + engines: {node: '>= 14'} + dev: false + /yargs-parser/20.2.4: resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} engines: {node: '>=10'} @@ -2452,3 +2875,7 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} dev: true + + /zod/3.21.4: + resolution: {integrity: sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==} + dev: false diff --git a/src/agent/index.ts b/src/agent/index.ts new file mode 100644 index 0000000..8b4325d --- /dev/null +++ b/src/agent/index.ts @@ -0,0 +1,144 @@ +import { AgentInput, Agent, Tool, AgentActionOutputParser, ChatConversationalAgentOutputParser } from "langchain/agents"; +import { BaseLanguageModel } from "langchain/base_language"; +import { LLMChain } from "langchain/chains"; +import { AgentArgs } from "langchain/dist/agents/agent"; +import { Optional } from "langchain/dist/types/type-utils"; +import { MessagesPlaceholder } from "langchain/prompts"; +import { ChatPromptTemplate } from "langchain/prompts"; +import { HumanMessagePromptTemplate } from "langchain/prompts"; +import { SystemMessagePromptTemplate } from "langchain/prompts"; +import { renderTemplate } from "langchain/prompts"; +import { + BaseOutputParser, + AgentStep, + BaseChatMessage, + AIChatMessage, + HumanChatMessage, +} from "langchain/schema"; +import { FORMAT_INSTRUCTIONS, SUFFIX } from "../services"; +import { DEFAULT_PREFIX, DEFAULT_SUFFIX, PREFIX_END, TEMPLATE_TOOL_RESPONSE } from "./prompt"; + +export type CreatePromptArgs = { + /** String to put after the list of tools. */ + systemMessage?: string; + /** String to put before the list of tools. */ + humanMessage?: string; + /** List of input variables the final prompt will expect. */ + inputVariables?: string[]; + /** Output parser to use for formatting. */ + outputParser?: AgentActionOutputParser; +}; + +export type ChatConversationalAgentInput = Optional; + +/** + * Agent for the MRKL chain. + * @augments Agent + */ +export class ChatConversationalAgent extends Agent { + constructor(input: ChatConversationalAgentInput) { + const outputParser = + input.outputParser ?? ChatConversationalAgent.getDefaultOutputParser(); + super({ ...input, outputParser }); + } + + _agentType() { + return "chat-conversational-react-description" as const; + } + + observationPrefix() { + return "Observation: "; + } + + llmPrefix() { + return "Thought:"; + } + + _stop(): string[] { + return ["Observation:"]; + } + + static validateTools(tools: Tool[]) { + const invalidTool = tools.find((tool) => !tool.description); + if (invalidTool) { + const msg = + `Got a tool ${invalidTool.name} without a description.` + + ` This agent requires descriptions for all tools.`; + throw new Error(msg); + } + } + + constructScratchPad(steps: AgentStep[]): BaseChatMessage[] { + const thoughts: BaseChatMessage[] = []; + for (const step of steps) { + thoughts.push(new AIChatMessage(step.action.log)); + thoughts.push( + new HumanChatMessage( + renderTemplate(TEMPLATE_TOOL_RESPONSE, "f-string", { + observation: step.observation, + }) + ) + ); + } + return thoughts; + } + + static getDefaultOutputParser(): AgentActionOutputParser { + return new ChatConversationalAgentOutputParser(); + } + + /** + * Create prompt in the style of the ChatConversationAgent. + * + * @param tools - List of tools the agent will have access to, used to format the prompt. + * @param args - Arguments to create the prompt with. + * @param args.systemMessage - String to put before the list of tools. + * @param args.humanMessage - String to put after the list of tools. + */ + static createPrompt(tools: Tool[], args?: CreatePromptArgs) { + const systemMessage = (args?.systemMessage ?? DEFAULT_PREFIX) + PREFIX_END; + const humanMessage = args?.humanMessage ?? DEFAULT_SUFFIX; + const outputParser = + args?.outputParser ?? new ChatConversationalAgentOutputParser(); + const toolStrings = tools + .map((tool) => `${tool.name}: ${tool.description}`) + .join("\n"); + const formatInstructions = renderTemplate(systemMessage, "f-string", { + format_instructions: outputParser.getFormatInstructions(), + }); + const toolNames = tools.map((tool) => tool.name).join("\n"); + const finalPrompt = renderTemplate(formatInstructions, "f-string", { + tools: toolStrings, + tool_names: toolNames, + }); + const messages = [ + SystemMessagePromptTemplate.fromTemplate(finalPrompt), + new MessagesPlaceholder("chat_history"), + HumanMessagePromptTemplate.fromTemplate(humanMessage), + new MessagesPlaceholder("agent_scratchpad"), + ]; + return ChatPromptTemplate.fromPromptMessages(messages); + } + + static fromLLMAndTools( + llm: BaseLanguageModel, + tools: Tool[], + args?: CreatePromptArgs & AgentArgs + ) { + ChatConversationalAgent.validateTools(tools); + const prompt = ChatConversationalAgent.createPrompt(tools, args); + const chain = new LLMChain({ + prompt, + llm, + callbackManager: args?.callbackManager, + }); + const outputParser = + args?.outputParser ?? ChatConversationalAgent.getDefaultOutputParser(); + + return new ChatConversationalAgent({ + llmChain: chain, + outputParser, + allowedTools: tools.map((t) => t.name), + }); + } +} diff --git a/src/agent/outputParser.ts b/src/agent/outputParser.ts new file mode 100644 index 0000000..bcb6372 --- /dev/null +++ b/src/agent/outputParser.ts @@ -0,0 +1,33 @@ +import { AgentActionOutputParser } from "langchain/agents.js"; +import { FORMAT_INSTRUCTIONS } from "./prompt.js"; + +export class ChatConversationalAgentOutputParser extends AgentActionOutputParser { + async parse(text: string) { + let jsonOutput = text.trim(); + if (jsonOutput.includes("```json")) { + jsonOutput = jsonOutput.split("```json")[1].trimStart(); + } + if (jsonOutput.includes("```")) { + jsonOutput = jsonOutput.split("```")[0].trimEnd(); + } + if (jsonOutput.startsWith("```")) { + jsonOutput = jsonOutput.slice(3).trimStart(); + } + if (jsonOutput.endsWith("```")) { + jsonOutput = jsonOutput.slice(0, -3).trimEnd(); + } + + const response = JSON.parse(jsonOutput); + + const { action, action_input } = response; + + if (action === "Final Answer") { + return { returnValues: { output: action_input }, log: text }; + } + return { tool: action, toolInput: action_input, log: text }; + } + + getFormatInstructions(): string { + return FORMAT_INSTRUCTIONS; + } +} diff --git a/src/agent/prompt.ts b/src/agent/prompt.ts new file mode 100644 index 0000000..4089549 --- /dev/null +++ b/src/agent/prompt.ts @@ -0,0 +1,64 @@ +export const DEFAULT_PREFIX = `Assistant is an software development AI. The user will provide you tools to develop software. +The user can only use one tool at the time, so never ask for more than one action per message. + +Assistant is designed to be able to develop software and answer questions exploring code bases. +As a language model, Assistant is able to generate human-like text based on the input it receives, +allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the +engineer pairing with the assistant. + +Overall, Assistant is a powerful software development system. Whether you need help developing software or help +understanding code bases and concepts, Assistant is here to assist. Never be lazy, only stop working when you found +an answer or you are sure you can't find it. NEVER assume, ALWAYS check. + +The Final Answer input can be markdown. + +TOOLS +------ +Assistant can ask the user to use tools to look up information that may be helpful in answering the users original question. The tools the human can use are: + +{{tools}} + +{format_instructions}`; + +export const PREFIX_END = ` However, above all else, all responses must adhere to the format of RESPONSE FORMAT INSTRUCTIONS.`; + +export const FORMAT_INSTRUCTIONS = `RESPONSE FORMAT INSTRUCTIONS +---------------------------- + +When responding to me please, please output a response in one of two formats: + +**Option 1:** +Use this if you want the human to use a tool. +Markdown code snippet formatted in the following schema: + +\`\`\`json +{{{{ + "action": string \\ The action to take. Must be one of {tool_names} + "action_input": string \\ The input to the action +}}}} +\`\`\` + +**Option #2:** +Use this if you want to respond directly to the human. Markdown code snippet formatted in the following schema: + +\`\`\`json +{{{{ + "action": "Final Answer", + "action_input": string \\ You should put what you want to return to use here +}}}} +\`\`\``; + +export const DEFAULT_SUFFIX = `USER'S INPUT +-------------------- +Here is the user's input (remember to respond with a markdown code snippet of a json blob with a single action, and NOTHING else): + +{input}`; + +export const TEMPLATE_TOOL_RESPONSE = `TOOL RESPONSE: +--------------------- +{observation} + +USER'S INPUT +-------------------- + +Okay, so what is the response to my original question? If using information from tools, you must say it explicitly - I have forgotten all TOOL RESPONSES! Remember to respond with a markdown code snippet of a json blob with a single action, and NOTHING else.`; diff --git a/src/commands/execute.ts b/src/commands/execute.ts deleted file mode 100644 index 57608e7..0000000 --- a/src/commands/execute.ts +++ /dev/null @@ -1,402 +0,0 @@ -import { Command } from "./parse"; -import * as vscode from "vscode"; -import { CodePrompt } from "../prompt"; -import { exec } from 'node:child_process'; -import { readFileSync } from "node:fs"; - -export interface Message { - role: "user" | "assistant" | "system"; - codePrompt?: CodePrompt[]; - text: string; -} - -interface CommandsContext { - state: { - codePrompts: CodePrompt[]; - currentUserRequest: string; - editor: vscode.TextEditor | undefined; - panel: vscode.WebviewPanel | undefined; - memory: string; - conversationHistory: Message[]; - }, - actions: { - loadUI: () => void; - } -} - -export const createExecuteCommands = (context: CommandsContext) => async (commands: Command[]): Promise => { - let { editor, codePrompts, currentUserRequest, panel, memory, conversationHistory } = context.state; - const { loadUI } = context.actions; - for (const command of commands) { - console.log("Executing command: " + command); - - const workspaceFolder = vscode.workspace.workspaceFolders?.[0].uri.fsPath; - let copy = false; - - const args = command.args; - switch (command.name) { - case "readFile": - if (!editor) { - throw new Error("No active editor"); - } - const readFilePath = args[0]; - const readFilePathUri = vscode.Uri.file(workspaceFolder + "/" + readFilePath); - const content = readFileSync(readFilePathUri.fsPath, 'utf8'); - const readFileStartLine = parseInt(args[1] ?? '0'); - const readFileEndLine = parseInt(args[2] ?? '20'); - - const selectedContent = content.split('\n').slice(readFileStartLine, readFileEndLine).join('\n'); - - codePrompts = [ - ...codePrompts, - { - type: "file", - location: readFilePath, - content: selectedContent, - totalLines: content.split('\n').length, - startLine: readFileStartLine, - } - ]; - loadUI(); - break; - case "listFiles": - // read the directory relative to the project root - const files = await vscode.workspace.fs.readDirectory( - vscode.Uri.file(workspaceFolder + "/" + args[0]) - ); - const fileStrings = files.map( - (f) => `${f[0]} (${vscode.FileType[f[1]]})` - ); - currentUserRequest += `response to @listFiles ${ - args[0] - }:\n\`\`\`\n${fileStrings.join("\n")}\n\`\`\``; - await panel?.webview.postMessage({ - type: "userRequest", - userRequest: currentUserRequest, - }); - break; - case "createFile": - const newFileUri = vscode.Uri.file(workspaceFolder + "/" + args[0]); - await vscode.workspace.fs.writeFile(newFileUri, new Uint8Array()); - break; - case "undo": - if (!editor) { - throw new Error("No active editor"); - } - await vscode.commands.executeCommand("undo"); - break; - case "redo": - if (!editor) { - throw new Error("No active editor"); - } - vscode.commands.executeCommand("redo"); - break; - case "input": - if (!editor) { - throw new Error("No active editor"); - } - const path = args[0]; - const insertLine = args[1]; - const insertColumn = args[2]; - const parsedText = args[3]; - const inputFileUri = vscode.Uri.file(workspaceFolder + "/" + path); - let inputDocument: vscode.TextDocument; - try { - inputDocument = await vscode.workspace.openTextDocument(inputFileUri); - } catch (e) { - await vscode.workspace.fs.writeFile(inputFileUri, new Uint8Array()); - inputDocument = await vscode.workspace.openTextDocument(inputFileUri); - } - editor = await vscode.window.showTextDocument(inputDocument); - - editor.selection = new vscode.Selection( - parseInt(insertLine), - parseInt(insertColumn), - parseInt(insertLine), - parseInt(insertColumn) - ); - await editor.edit((editBuilder) => { - if (!editor) { - throw new Error("No active editor"); - } - editBuilder.insert(editor.selection.active, parsedText); - }); - // get 20 lines before and after the cursor - const startLineInput = Math.max(0, editor.selection.active.line - 20); - const endLineInput = Math.min( - editor.document.lineCount - 1, - editor.selection.active.line + parsedText.split("\n").length + 20 - ); - const range = new vscode.Range( - startLineInput, - 0, - endLineInput, - editor.document.lineAt(endLineInput).text.length - ); - const text = editor.document.getText(range); - currentUserRequest += `response to @input:\n\`\`\`\n${text}\n\`\`\``; - await panel?.webview.postMessage({ - type: "userRequest", - userRequest: currentUserRequest, - }); - break; - case "select": - if (!editor) { - throw new Error("No active editor"); - } - const startLine = parseInt(args[0]); - const startColumn = parseInt(args[1]); - const endLine = parseInt(args[2]); - const endColumn = parseInt(args[3]); - editor.selection = new vscode.Selection( - startLine, - startColumn, - endLine, - endColumn - ); - const selectedText = editor.document.getText(editor.selection); - currentUserRequest += `response to @select:\n\`\`\`\n${selectedText}\n\`\`\``; - await panel?.webview.postMessage({ - type: "userRequest", - userRequest: currentUserRequest, - }); - break; - case "replace": - if (!editor) { - throw new Error("No active editor"); - } - const replacePath = args[0]; - const replaceStartLine = parseInt(args[1]); - const replaceStartColumn = parseInt(args[2]); - const replaceEndLine = parseInt(args[3]); - const replaceEndColumn = parseInt(args[4]); - const replaceText = args[5]; - const replaceFileUri = vscode.Uri.file( - workspaceFolder + "/" + replacePath - ); - const replaceDocument = await vscode.workspace.openTextDocument( - replaceFileUri - ); - editor = await vscode.window.showTextDocument(replaceDocument); - await editor.edit((editBuilder) => { - editBuilder.replace( - new vscode.Range( - replaceStartLine, - replaceStartColumn, - replaceEndLine, - replaceEndColumn - ), - replaceText - ); - }); - break; - case "copy": - copy = true; - case "cut": - if (!editor) { - throw new Error("No active editor"); - } - const cutPath = args[0]; - const copyStartLine = parseInt(args[1]); - const copyStartColumn = parseInt(args[2]); - const copyEndLine = parseInt(args[3]); - const copyEndColumn = parseInt(args[4]); - const copyRange = new vscode.Range( - copyStartLine, - copyStartColumn, - copyEndLine, - copyEndColumn - ); - const cutDocument = await vscode.workspace.openTextDocument( - vscode.Uri.file(workspaceFolder + "/" + cutPath) - ); - const copyText = cutDocument.getText(copyRange); - vscode.env.clipboard.writeText(copyText); - if (!copy) { - await editor.edit((editBuilder) => { - editBuilder.delete(copyRange); - }); - } - break; - case "paste": - if (!editor) { - throw new Error("No active editor"); - } - const pastePath = args[0]; - const pasteLine = parseInt(args[1]); - const pasteColumn = parseInt(args[2]); - const pasteDocument = await vscode.workspace.openTextDocument( - vscode.Uri.file(workspaceFolder + "/" + pastePath) - ); - const pasteText = await vscode.env.clipboard.readText(); - const pasteRange = new vscode.Range( - pasteLine, - pasteColumn, - pasteLine, - pasteColumn - ); - editor = await vscode.window.showTextDocument(pasteDocument); - - await editor.edit((editBuilder) => { - if (!editor) { - throw new Error("No active editor"); - } - editBuilder.insert(pasteRange.start, pasteText); - }); - - break; - case "getSyntaxErrors": - if (!editor) { - throw new Error("No active editor"); - } - const diagnostics = vscode.languages.getDiagnostics( - editor.document.uri - ); - const syntaxErrors = diagnostics.filter( - (d) => d.severity === vscode.DiagnosticSeverity.Error - ); - const syntaxErrorMessages = syntaxErrors.map((d) => d.message); - const syntaxErrorLines = syntaxErrors.map((d) => d.range.start.line); - const syntaxErrorColumns = syntaxErrors.map( - (d) => d.range.start.character - ); - const syntaxErrorLengths = syntaxErrors.map( - (d) => d.range.end.character - d.range.start.character - ); - const syntaxErrorData = syntaxErrorMessages.map((m, i) => { - return { - message: m, - line: syntaxErrorLines[i], - column: syntaxErrorColumns[i], - length: syntaxErrorLengths[i], - }; - }); - currentUserRequest += `response to @getSyntaxErrors:\n\`\`\`\n${JSON.stringify( - syntaxErrorData, - null, - 2 - )}\n\`\`\``; - panel?.webview.postMessage({ - type: "syntaxErrors", - userRequest: currentUserRequest, - }); - break; - case "search": - const query = args[0]; - const searchResults: { - file: vscode.Uri; - range: vscode.Range; - preview: { - text: string; - matches: vscode.Range[]; - }; - }[] = await vscode.commands.executeCommand( - "workbench.action.findInFiles", - { - query, - triggerSearch: true, - isRegex: true, - isCaseSensitive: false, - isWordMatch: false, - filesToInclude: "**/*", - filesToExclude: "**/node_modules/**", - useExcludesAndIgnoreFiles: true, - previewOptions: { - matchLines: 1, - charsPerLine: 100, - }, - } - ); - console.log(JSON.stringify(searchResults)); - const searchResultsData = searchResults.map((r) => { - return { - file: r.file.fsPath, - line: r.range.start.line, - column: r.range.start.character, - length: r.range.end.character - r.range.start.character, - }; - }); - - currentUserRequest += `response to @search:\n\`\`\`\n${JSON.stringify( - searchResultsData, - null, - 2 - )}\n\`\`\``; - panel?.webview.postMessage({ - type: "searchResults", - userRequest: currentUserRequest, - }); - break; - case "runInTerminal": - const terminalCommand = args[0]; - - // Open a confirmation modal in VS Code - const confirmation = await vscode.window.showInformationMessage( - `Allow PromptMate to run "${terminalCommand}" in the terminal?`, - "Allow", - "Cancel" - ); - - if (confirmation !== "Allow") { - break; - } - - const output = await new Promise((resolve, reject) => { - exec( - terminalCommand, - { - cwd: workspaceFolder, - }, - (error, stdout, stderr) => { - if (error) { - console.log(`error: ${error.message}`); - resolve(error.message); - return; - } - if (stderr) { - console.log(`stderr: ${stderr}`); - resolve(stderr); - return; - } - resolve(stdout); - } - ); - }); - - currentUserRequest += `response to @runInTerminal:\n\`\`\`\n${output}\n\`\`\``; - await panel?.webview.postMessage({ - type: "userRequest", - userRequest: currentUserRequest, - }); - break; - case "memoryWrite": - const data = args[0]; - memory += data; - break; - case "readMemory": - currentUserRequest += `response to @readMemory:\n\`\`\`\n${memory}\n\`\`\``; - await panel?.webview.postMessage({ - type: "userRequest", - userRequest: currentUserRequest, - }); - break; - case "clearMemory": - memory = ""; - break; - case "clearConversation": - conversationHistory = []; - break; - default: - console.log("Unknown command:", command); - } - } - - return { - codePrompts, - currentUserRequest, - editor, - panel, - memory, - conversationHistory, - }; -}; diff --git a/src/commands/parse.ts b/src/commands/parse.ts deleted file mode 100644 index b664166..0000000 --- a/src/commands/parse.ts +++ /dev/null @@ -1,99 +0,0 @@ -export class Command { - name: string; - args: string[]; - - constructor(name: string, args: string[] = []) { - this.name = name; - this.args = args; - } -} - -export function parseLine(line: string): [string, string[]] | undefined { - if (!line.startsWith("@")) { - return; - } - const parts = line.slice(1).match(/(?:[^\s"]+|"[^"]*")+/g) || []; - const name = parts[0]; - const args = parts.slice(1).map((arg) => { - try{ - return JSON.parse(arg); - } catch (e) { - if(name === "input") { - throw new Error(`Invalid input: ${arg} ${e}`); - } - return arg; - } - }); - - if (!name) { - return; - } - - return [name, args]; -} - -export function parseCommands(input: string): Command[] { - const lines = input.split("\n"); - const commands: Command[] = []; - let parsing = false; - let parsingInput = false; - let parsingReplace = false; - let parsingMemoryWrite = false; - let inputText = ""; - let currentCommand: Command | null = null; - - for (const line of lines) { - const parseResult = parseLine(line); - if (!parseResult) { - if (parsingInput || parsingReplace) { - inputText += line + "\n"; - } - continue; - } - - const [name, args] = parseResult; - - if (name === "startCommand") { - parsing = true; - } else if (name === "endCommand") { - parsing = false; - } else if (parsing && name) { - if (name === "startInput") { - parsingInput = true; - currentCommand = new Command("input", args); - } else if (name === "endInput") { - parsingInput = false; - if (currentCommand) { - const inputArgs = [...currentCommand.args, inputText.trim()]; - commands.push(new Command(currentCommand.name, inputArgs)); - inputText = ""; - currentCommand = null; - } - } else if (name === "startReplace") { - parsingReplace = true; - currentCommand = new Command("replace", args); - } else if (name === "endReplace") { - if (currentCommand) { - const inputArgs = [...currentCommand.args, inputText.trim()]; - commands.push(new Command(currentCommand.name, inputArgs)); - inputText = ""; - currentCommand = null; - } - } else if (name === "startMemoryWrite") { - parsingMemoryWrite = true; - currentCommand = new Command("memoryWrite", args); - } else if (name === "endMemoryWrite") { - if (currentCommand) { - const inputArgs = [...currentCommand.args, inputText.trim()]; - commands.push(new Command(currentCommand.name, inputArgs)); - inputText = ""; - currentCommand = null; - } - } else if (!parsingInput && !parsingReplace && !parsingMemoryWrite) { - commands.push(new Command(name, args)); - } - } - } - - return commands; -} diff --git a/src/extension.ts b/src/extension.ts index 0eb54af..1165233 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,14 +1,19 @@ import * as vscode from "vscode"; import { micromark } from "micromark"; -import {parseLine, Command, parseCommands} from "./commands/parse"; import "dotenv/config"; import html from "./index.html"; -import { askGPT, getModels } from "./services"; -import { createExecuteCommands, Message } from "./commands/execute"; +import { createAgentConversation, getModels } from "./services"; +import { Message } from "./tools"; import { handleAddPromptEvent, CodePrompt as CodePrompt } from "./prompt"; +import './fetch-polyfill'; +export async function activate(context: vscode.ExtensionContext) { + const generateConversationAgent = () => { + if (openAIKey) { + return createAgentConversation(model, openAIKey, autonomous, serperApiKey); + } + }; -export function activate(context: vscode.ExtensionContext) { let panel: vscode.WebviewPanel | undefined; let conversationHistory: Message[] = []; let codePrompts: CodePrompt[] = []; @@ -16,17 +21,20 @@ export function activate(context: vscode.ExtensionContext) { vscode.window.activeTextEditor; let currentUserRequest = ""; let models: string[] = []; - let token: string | undefined = context.globalState.get( + let openAIKey: string | undefined = context.globalState.get( "openaiUserToken", - "" + undefined + ); + let serperApiKey: string | undefined = context.globalState.get( + "serperAPIKey", + undefined ); let renderMarkdown = true; let model = context.globalState.get("openaiModel", "gpt-3.5-turbo"); let loading = false; let lastConversationLength = 0; - let memory = ""; let autonomous = context.globalState.get("autonomous", false); - let noVerification = context.globalState.get("noVerification", false); + let conversationAgent = await generateConversationAgent(); const loadUI = () => { if (panel) { @@ -39,15 +47,20 @@ export function activate(context: vscode.ExtensionContext) { }); panel?.webview.onDidReceiveMessage(async (message) => { - if (message.type === "askGPT" && !loading && token) { + if (message.type === "askGPT" && !loading && openAIKey) { await handleAskGPTEvent(message); } else if (message.type === "updateToken") { + console.log(message); context.globalState.update("openaiUserToken", message.token); - token = message.token; + context.globalState.update("serperAPIKey", message.serperApiKey); + openAIKey = message.token; + serperApiKey = message.serperApiKey; + conversationAgent = await generateConversationAgent(); await loadModels(); } else if (message.type === "updateModel") { context.globalState.update("openaiModel", message.model); model = message.model; + conversationAgent = await generateConversationAgent(); } else if (message.type === "addPrompt") { codePrompts = await handleAddPromptEvent( lastActiveEditor, @@ -59,21 +72,20 @@ export function activate(context: vscode.ExtensionContext) { } else if (message.type === "updateQuestion") { currentUserRequest = message.userRequest; } else if (message.type === "init") { - if (token) { + if (openAIKey) { await loadModels(); } } else if (message.type === "clearConversation") { conversationHistory = []; + conversationAgent?.getMemory().clear(); }else if (message.type === "toggleMarkdown") { handleToggleMarkdownEvent(); }else if (message.type === "deleteMessage") { conversationHistory.splice(message.index, 1); + (await conversationAgent?.getMemory().chatHistory.getMessages())?.splice(message.index, 1); }else if (message.type === "updateAutonomous") { autonomous = message.autonomous; context.globalState.update("autonomous", message.autonomous); - }else if (message.type === "updateNoVerification") { - noVerification = message.noVerification; - context.globalState.update("noVerification", message.noVerification); } await updateUI(); @@ -99,7 +111,8 @@ export function activate(context: vscode.ExtensionContext) { type: "prompt", prompt: codePrompts ? [...codePrompts] : undefined, }); - await panel?.webview.postMessage({ type: "token", token }); + await panel?.webview.postMessage({ type: "token", token: openAIKey }); + await panel?.webview.postMessage({ type: "serperApiKey", serperApiKey }); await panel?.webview.postMessage({ type: "currentFullPrompt", fullPrompt: buildPrompt(codePrompts, currentUserRequest), @@ -107,7 +120,6 @@ export function activate(context: vscode.ExtensionContext) { await panel?.webview.postMessage({ type: "model", model }); await panel?.webview.postMessage({ type: "models", models }); await panel?.webview.postMessage({ type: "autonomous", autonomous }); - await panel?.webview.postMessage({ type: "noVerification", noVerification }); }; const handleToggleMarkdownEvent = async () => { @@ -128,100 +140,26 @@ export function activate(context: vscode.ExtensionContext) { }); await updateUI(); - - const response = await askGPT( - message.token, - conversationHistory.map((m) => ({ - role: m.role, - content: buildPrompt(m.codePrompt, m.text), - })), - model, - autonomous, - ); - - if (!response.ok) { + + + const response = await conversationAgent?.ask(buildPrompt([...codePrompts], message.userRequest)); + + if(!response) { loading = false; conversationHistory.splice(-1); - if (response.code === "context_length_exceeded") { - vscode.window.showErrorMessage( - "Conversation length exceeded, remove some messages." - ); - } else { - vscode.window.showErrorMessage("Failed to fetch response, try again."); - } + vscode.window.showErrorMessage("Failed to fetch response, try again."); return; } conversationHistory.push({ role: "assistant", - text: response.data, + text: response.output, }); clearCurrentPrompt(); - if(!autonomous) { - loading = false; - return; - } - - const agentCommandsResult = await handleAgentCommands(response.data); - loading = false; - - if (!agentCommandsResult.ok) { - return; - } - - if ((currentUserRequest.length > 0 || codePrompts.length > 0) && !error && noVerification) { - await handleAskGPTEvent({ - token: message.token, - userRequest: currentUserRequest, - codePrompt: [...codePrompts], - }); - } }; - - const handleAgentCommands = async (data: string) => { - const executeCommands = createExecuteCommands({ - state: { - codePrompts, - currentUserRequest, - editor: vscode.window.activeTextEditor ?? lastActiveEditor, - panel, - memory, - conversationHistory, - }, - actions: { - loadUI, - }, - }); - - try { - // Execute the commands from the AI response. - const commands = parseCommands(data); - const newContext = await executeCommands(commands); - codePrompts = newContext.codePrompts; - currentUserRequest = newContext.currentUserRequest; - lastActiveEditor = newContext.editor; - return {ok: true}; - } catch (e) { - if (e instanceof Error) { - currentUserRequest += e.message; - await panel?.webview.postMessage({ - type: "userRequest", - userRequest: currentUserRequest, - }); - vscode.window.showErrorMessage("Command error"); - console.error(e); - } else { - throw e; - } - return { - ok: false - }; - } - }; - const clearCurrentPrompt = () => { codePrompts = []; @@ -233,13 +171,13 @@ export function activate(context: vscode.ExtensionContext) { }; const loadModels = async () => { - if (!token) { + if (!openAIKey) { vscode.window.showErrorMessage( "Failed to fetch models, please check your token" ); return; } - const response = await getModels(token); + const response = await getModels(openAIKey); if (!response.ok) { vscode.window.showErrorMessage( "Failed to fetch models, please check your token" @@ -297,41 +235,6 @@ export function activate(context: vscode.ExtensionContext) { }) ); - context.subscriptions.push( - vscode.commands.registerCommand("promptmate.runCommand", async () => { - const command = await vscode.window.showInputBox({ - prompt: "Enter a command", - }); - - if(!command){ - return; - } - const parsedLine = parseLine(command); - - if(!parsedLine){ - return; - } - - const [name, args] = parsedLine; - - const executeCommands = createExecuteCommands({ - state: { - codePrompts, - currentUserRequest, - editor: vscode.window.activeTextEditor ?? lastActiveEditor, - panel, - memory, - conversationHistory, - }, - actions: { - loadUI, - }, - }); - - await executeCommands([new Command(name, args)]); - }) - ); - vscode.window.onDidChangeActiveTextEditor( (editor) => { if (editor) { diff --git a/src/fetch-polyfill.ts b/src/fetch-polyfill.ts new file mode 100644 index 0000000..55f7c55 --- /dev/null +++ b/src/fetch-polyfill.ts @@ -0,0 +1,17 @@ +import fetch, { + Headers, + Request, + Response, +} from 'node-fetch'; + +// @ts-ignore +if (!globalThis.fetch) { +// @ts-ignore + globalThis.fetch = fetch; +// @ts-ignore + globalThis.Headers = Headers; +// @ts-ignore + globalThis.Request = Request; +// @ts-ignore + globalThis.Response = Response; +} diff --git a/src/index.html b/src/index.html index 1ddd235..2e847a0 100644 --- a/src/index.html +++ b/src/index.html @@ -132,6 +132,10 @@ box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); width: 100px; } + #serper-api-key { + box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); + width: 100px; + } #model { box-shadow: 0 0 5px rgba(0, 0, 0, 0.5); @@ -337,9 +341,13 @@

PromptMate

- - - + + +
+
+ + +
@@ -370,13 +378,9 @@

Conversation

- +
-
- - -
@@ -396,6 +400,7 @@

Conversation

const vscode = acquireVsCodeApi(); const token = document.getElementById("token"); + const serperApiKey = document.getElementById("serper-api-key"); const promptDisplay = document.getElementById("prompt-display"); const messageArea = document.getElementById("message-area"); const submit = document.getElementById("submit"); @@ -416,7 +421,6 @@

Conversation

const toggleMarkdownButton = document.getElementById("toggle-markdown"); const loadingSpinner = document.getElementById("loading-spinner"); const autonomous = document.getElementById("autonomous"); - const noVerification = document.getElementById("no-verification"); let modelValue; let modelsLoaded = false; @@ -432,6 +436,7 @@

Conversation

vscode.postMessage({ type: "updateToken", token: token.value, + serperApiKey: serperApiKey.value, }); }); @@ -498,13 +503,6 @@

Conversation

}); }); - noVerification.addEventListener("change", () => { - vscode.postMessage({ - type: "updateNoVerification", - noVerification: noVerification.checked, - }); - }); - window.addEventListener("message", (event) => { if (event.data.type === "prompt") { promptDisplay.innerHTML = ""; @@ -555,6 +553,8 @@

Conversation

conversation.prepend(messageElement); }); + + conversation.scrollTop = conversation.scrollHeight; clearConversation.style.display = "block"; } else if (event.data.type === "loading") { @@ -566,6 +566,12 @@

Conversation

} else { token.value = ""; } + } else if (event.data.type === "serperApiKey") { + if(event.data.serperApiKey !== undefined) { + serperApiKey.value = event.data.serperApiKey; + } else { + serperApiKey.value = ""; + } } else if (event.data.type === "currentFullPrompt") { fullPrompt.innerText = event.data.fullPrompt; } else if (event.data.type === "models") { @@ -600,8 +606,6 @@

Conversation

messageArea.value = event.data.userRequest; } else if (event.data.type === "autonomous") { autonomous.checked = event.data.autonomous; - } else if (event.data.type === "noVerification") { - noVerification.checked = event.data.noVerification; } }); diff --git a/src/memory/index.ts b/src/memory/index.ts new file mode 100644 index 0000000..676b106 --- /dev/null +++ b/src/memory/index.ts @@ -0,0 +1,141 @@ +import { BaseLanguageModel } from "langchain/base_language"; +import { BaseChatMessage, SystemChatMessage, InputValues, ChatMessage } from "langchain/schema"; +import { BaseChatMemory, ChatMessageHistory } from "langchain/memory"; +import { SUMMARY_PROMPT } from "./prompt"; +import { BasePromptTemplate } from "langchain/prompts"; +import { LLMChain } from "langchain/chains"; + +export interface BaseMemoryInput { + chatHistory?: ChatMessageHistory; + returnMessages?: boolean; + inputKey?: string; + outputKey?: string; +} + +export type ConversationSummaryMemoryInput = BaseMemoryInput & { + memoryKey?: string; + humanPrefix?: string; + aiPrefix?: string; + llm: BaseLanguageModel; + prompt?: BasePromptTemplate; + summaryChatMessageClass?: new (content: string) => BaseChatMessage; +}; + +export type OutputValues = Record; +export type MemoryVariables = Record; + +export const getInputValue = (inputValues: InputValues, inputKey?: string): string => { + if (inputKey !== undefined) { + return inputValues[inputKey]; + } + const keys = Object.keys(inputValues); + if (keys.length === 1) { + return inputValues[keys[0]]; + } + + return JSON.stringify(inputValues); +}; + +export class ConversationSummaryMemory extends BaseChatMemory { + buffer = ""; + + memoryKey = "history"; + + humanPrefix = "Human"; + + aiPrefix = "AI"; + + llm: BaseLanguageModel; + + prompt: BasePromptTemplate = SUMMARY_PROMPT; + + summaryChatMessageClass: new (content: string) => BaseChatMessage = + SystemChatMessage; + + constructor(fields?: ConversationSummaryMemoryInput) { + const { + returnMessages, + inputKey, + outputKey, + chatHistory, + humanPrefix, + aiPrefix, + llm, + prompt, + summaryChatMessageClass, + } = fields ?? {}; + + super({ returnMessages, inputKey, outputKey, chatHistory }); + + this.memoryKey = fields?.memoryKey ?? this.memoryKey; + this.humanPrefix = humanPrefix ?? this.humanPrefix; + this.aiPrefix = aiPrefix ?? this.aiPrefix; + this.llm = llm!; + this.prompt = prompt ?? this.prompt; + this.summaryChatMessageClass = + summaryChatMessageClass ?? this.summaryChatMessageClass; + } + + async predictNewSummary( + messages: BaseChatMessage[], + existingSummary: string + ): Promise { + const newLines = getBufferString(messages, this.humanPrefix, this.aiPrefix); + const chain = new LLMChain({ llm: this.llm, prompt: this.prompt }); + return await chain.predict({ + summary: existingSummary, + new_lines: newLines, + }); + } + + async loadMemoryVariables(_: InputValues): Promise { + if (this.returnMessages) { + const result = { + [this.memoryKey]: [new this.summaryChatMessageClass(this.buffer)], + }; + return result; + } + const result = { [this.memoryKey]: this.buffer }; + return result; + } + + async saveContext( + inputValues: InputValues, + outputValues: OutputValues + ): Promise { + this.chatHistory.addUserMessage(getInputValue(inputValues, this.inputKey)); + this.chatHistory.addAIChatMessage( + getInputValue(outputValues, this.outputKey) + ); + const messages = await this.chatHistory.getMessages(); + this.buffer = await this.predictNewSummary(messages.slice(-2), this.buffer); + } + + async clear() { + await super.clear(); + this.buffer = ""; + } +} +function getBufferString( + messages: BaseChatMessage[], + human_prefix = "Human", + ai_prefix = "AI" +): string { + const string_messages: string[] = []; + for (const m of messages) { + let role: string; + if (m._getType() === "human") { + role = human_prefix; + } else if (m._getType() === "ai") { + role = ai_prefix; + } else if (m._getType() === "system") { + role = "System"; + } else if (m._getType() === "generic") { + role = (m as ChatMessage).role; + } else { + throw new Error(`Got unsupported message type: ${m}`); + } + string_messages.push(`${role}: ${m.text}`); + } + return string_messages.join("\n"); +} diff --git a/src/memory/prompt.ts b/src/memory/prompt.ts new file mode 100644 index 0000000..96a84f6 --- /dev/null +++ b/src/memory/prompt.ts @@ -0,0 +1,36 @@ +import { PromptTemplate } from "langchain/prompts"; + +const _DEFAULT_SUMMARIZER_TEMPLATE = `Progressively summarize the lines of conversation provided, adding onto the previous summary returning a new summary. + +EXAMPLE +Current summary: +- Human asked for the list of files in the folder ./src +- Agent used the tool to list files and answered with a list of files of a JavaScript VS Code extension +- Human asked what this project was about +- Agent used the tool to read a file and read the extension.ts file, and answered with a description of the project + + +New lines of conversation: +Human: Implement tests for extension.ts +AI: I just create extension.test.ts with tests for your file. + +New summary: +- Human was exploring and understanding the project +- Agent listed the ./src folder, identified it is a VS Code extension, and read the extension.ts file and answered with a description of the project +- Human: Implement tests for extension.ts +- AI: I just create extension.test.ts with tests for extensions.ts. +END OF EXAMPLE + +Current summary: +{summary} + +New lines of conversation: +{new_lines} + +New summary:`; + +// eslint-disable-next-line spaced-comment +export const SUMMARY_PROMPT = /*#__PURE__*/ new PromptTemplate({ + inputVariables: ["summary", "new_lines"], + template: _DEFAULT_SUMMARIZER_TEMPLATE, +}); diff --git a/src/prompt.ts b/src/prompt.ts index 23be87a..407820a 100644 --- a/src/prompt.ts +++ b/src/prompt.ts @@ -1,5 +1,5 @@ -import path = require("path"); -import ts = require("typescript"); +import * as path from "path"; +import * as ts from "typescript"; import * as vscode from "vscode"; interface FunctionPrompt { diff --git a/src/services.ts b/src/services.ts index 442ff1c..46e35c2 100644 --- a/src/services.ts +++ b/src/services.ts @@ -1,139 +1,11 @@ +import { ChatOpenAI } from "langchain/chat_models/openai"; import axios from "axios"; - -/* -const systemPrompt = `You are a helpful assistant that will be helping develop software. -You are going to receive files, functions and selection to give you context. -You can ask me questions about the code and I will try to answer them. -You may request more code snippets to help you understand the code. -Provide code snippets whenever you can.`; -*/ - -const autonomousSystemPrompt = `You are a advanced programming AI that will develop software autonomously using commands. -The set of available commands are: -@startCommand - Always start a set of commands with this. -@listFiles - List all files in a directory, the path is relative to the root directory, the output will be returned in an answer. -@readFile - Read a file, the path is relative to the root directory, the output will be returned in an answer. startLine and endLine are optional. If not provided, only the first 20 lines are answered. -@startInput - Start inputting code. - -@endInput - End inputting code. -@select - Select a piece of code, the selection will be returned in an answer. -@startReplace - Start replacing code. - -@endReplace - End replacing code. -@createFile - Create a file, the path is relative to the root directory. -@redo - Redo the last command in the open editor. -@undo - Undo the last command in the open editor. -@copy - Copy selected text into clipboard. -@cut - Cut selected text into clipboard. -@paste - Paste clipboard into editor. -@getSyntaxErrors - Get syntax errors in the open editor. -@runInTerminal - Run a command in the terminal, the output will be returned in an answer. -@startMemoryWrite - Start writing to memory. - -@endMemoryWrite - End writing to memory. -@readMemory - Read memory, the output will be returned in an answer. -@clearMemory - Clear memory. -@clearConversation - Clear conversation history. -@endCommand - -When using commands, make sure to input code in the correct line and column. -Correct problems using @undo. Obey orders by executing commands without asking for permission. -Always check for syntax errors after @input, @paste, and @cut. - -Output should follow a format similar to the output examples, explaining long and short term goals. -Do not do multiple @startCommand and @endCommand in the same message. - -In case of errors or unexpected situations, provide a clear explanation of the issue and suggest possible solutions. -Be creative and think outside the box when providing solutions, but always prioritize accuracy and adherence to the given guidelines. - -Fill the context with all relevant information to guarantee that old messages may be deleted but context will be kept. -Old messages are deleted, so keep in memory all the information you may need to achieve your goals. - -Paths are always relative to the workspace root directory. -Keep the messages as short as possible, but always provide enough context to understand the code. -Avoid reading too many files, the input/output has a limit of 8000 tokens. - -Output example: -- Long term goal: Develop a AGI that can develop software autonomously. -- Short term goal: Understand project. - -@startCommand -@startMemoryWrite -[-] Develop a AGI that can develop software autonomously. - [ ] Understand project. - [x] Understand code. - [ ] Understand context. - [ ] Understand commands. - [ ] Understand output. -@endMemoryWrite -@listFiles . -@endCommand - -Output example: -- Context: - - This is a project of a game for kids. - - The game is a platformer. - - The game is a 2D game. - - It follows an MVC pattern. -- Long term goal: Develop a fun game in TypeScript. -- Short term goal: write the entrypoint. - -@startCommand -@createFile src/index.ts -@endCommand - -Output example: -- Context: - - This is a project of a OpenAI assistant. -- Long term goal: Improve code quality. -- Short term goal: Copy function to new file. - -@startCommand -@edit src/index.ts -@readCurrentFile -@copy 0 0 78 100 -@createFile src/utils.ts -@paste -@endCommand - -Output example: -- Context: - - This is an TypeScript project. - - Implements an web server. -- Long term goal: Improve code quality. -- Short term goal: Refactor function. - -@startCommand -@edit "src/utils.ts" -@readCurrentFile -@startInput "src/util.ts" 7 0 - console.log("AI added this line"); - const niceCode = "AI is nice"; -@endInput -@readMemory -@clearMemory -@startMemoryWrite - -@endCommand - -@startCommand -@runInTerminal "cargo check" -@endCommand - -Remember, your main goal is to provide accurate, creative, and efficient solutions while following the given guidelines and commands. - -Always read the memory before doing anything to check your long-term plans and desires. - -Always keep the memory updated with long-term goals, plans, desires, hypothesis, and critiques. - -Always output commands, only output plain text when requested. -`; - -const nonAutonomousSystemPrompt = `You are a helpful assistant that will be helping develop software. -You are going to receive files, functions and selection to give you context. -You can ask me questions about the code and I will try to answer them. -You may request more code snippets to help you understand the code. -Provide code snippets whenever you can.`; +import { createTools } from "./tools"; +import { CallbackManager } from "langchain/callbacks"; +import { ConversationSummaryMemory } from "./memory"; +import * as vscode from "vscode"; +import { AgentExecutor } from "langchain/agents"; +import { ChatConversationalAgent } from "./agent"; interface ResponseFail { @@ -145,72 +17,6 @@ interface ResponseOk { data: T; } -export async function askGPT( - token: string, - messages: { - role: "user" | "assistant" | "system"; - content: string; - }[] = [], - model: string = "gpt-4", - autonomous: boolean = false -): Promise> { - const data = { - model, - messages: [ - { role: "system", content: autonomous ? autonomousSystemPrompt : nonAutonomousSystemPrompt }, - ...messages, - ], - temperature: 0.2, - }; - - const config = { - headers: { - "Content-Type": "application/json", - Authorization: `Bearer ${token}`, - }, - }; - - let code = undefined; - try { - console.log("Sending request to OpenAI..."); - const response = await axios.post( - "https://api.openai.com/v1/chat/completions", - data, - config - ); - console.log("Received response from OpenAI."); - return { - data: response.data.choices[0].message.content, - ok: true, - }; - } catch (error: unknown) { - if (axios.isAxiosError(error)) { - if (error.response) { - code = error.response.data.error.code; - // The request was made and the server responded with a status code - // that falls out of the range of 2xx - console.log(JSON.stringify(error.response.data, null, 2)); - console.log(error.response.status); - console.log(error.response.headers); - } else if (error.request) { - // The request was made but no response was received - // `error.request` is an instance of XMLHttpRequest in the browser and an instance of - // http.ClientRequest in node.js - console.log(error.request); - } else { - // Something happened in setting up the request that triggered an Error - console.log("Error", error.message); - } - console.log(error.config); - } - - return { - ok: false, - code, - }; - } -} - export async function getModels(token: string): Promise> { @@ -238,3 +44,91 @@ export async function getModels(token: string): Promise { + const model = new ChatOpenAI({ + temperature: 0, + modelName, + openAIApiKey: apiKey, + verbose: true, + }); + const tools = createTools(apiKey, serperAPIKey, autonomous); + + const memory = new ConversationSummaryMemory({ + returnMessages: true, + memoryKey: "chat_history", + inputKey: "input", + llm: model, + }); + const executor = AgentExecutor.fromAgentAndTools({ + agent: ChatConversationalAgent.fromLLMAndTools(model, tools), + tools, + memory: memory, + returnIntermediateSteps: true, + verbose: true, + }); + + return { + getMemory() { + return memory; + }, + async ask(message: string) { + const response = await executor.call({ input: message }); + return response; + } + }; +}; diff --git a/src/tools/index.ts b/src/tools/index.ts new file mode 100644 index 0000000..18efd2b --- /dev/null +++ b/src/tools/index.ts @@ -0,0 +1,502 @@ +import * as vscode from "vscode"; +import { CodePrompt } from "../prompt"; +import { exec } from "node:child_process"; +import { readFileSync } from "node:fs"; +import { DynamicTool } from "langchain/tools"; +import { ChatOpenAI } from "langchain/chat_models/openai"; +import { RecursiveCharacterTextSplitter } from "langchain/text_splitter"; +import { loadSummarizationChain, loadQAMapReduceChain } from "langchain/chains"; +import { WebBrowser } from "langchain/tools/webbrowser"; +import { OpenAIEmbeddings } from "langchain/embeddings/openai"; +import { Serper } from "langchain/tools"; + +export interface Message { + role: "user" | "assistant" | "system"; + codePrompt?: CodePrompt[]; + text: string; +} + +export function createTools( + openAIApiKey: string, + serperAPIKey: string | undefined, + autonomous: boolean +) { + const workspaceFolder = vscode.workspace.workspaceFolders?.[0].uri.fsPath; + let editor = vscode.window.activeTextEditor; + const model = new ChatOpenAI({ temperature: 0, openAIApiKey }); + const embeddings = new OpenAIEmbeddings({ openAIApiKey }); + const browser = new WebBrowser({ model, embeddings }); + const extraTools = serperAPIKey ? [new Serper(serperAPIKey)] : []; + const textSplitter = new RecursiveCharacterTextSplitter({ + chunkSize: 1000, + }); + const summarizationChain = loadSummarizationChain(model); + const qaChain = loadQAMapReduceChain(model); + + const readFileSummary = new DynamicTool({ + name: "readFileSummary", + description: + "Provide a summary about the content of a file in the file system. Preferably use this instead of readFile. Expects the relative path as input and outputs the file content.", + func: async (relativePath: string) => { + try { + const readFilePath = relativePath; + const readFilePathUri = vscode.Uri.file( + workspaceFolder + "/" + readFilePath + ); + const content = readFileSync(readFilePathUri.fsPath, "utf8"); + const docs = await textSplitter.createDocuments([content]); + + // This convenience function creates a document chain prompted to summarize a set of documents. + const res = await summarizationChain.call({ + input_documents: docs, + }); + return res.text; + } catch (e) { + return e; + } + }, + }); + + const readFile = new DynamicTool({ + name: "readFile", + description: + "Reads a file in the file system. Use this when the summary was not enough. Expects the relative path as input and outputs the file content.", + func: async (relativePath: string) => { + try { + const readFilePath = relativePath; + const readFilePathUri = vscode.Uri.file( + workspaceFolder + "/" + readFilePath + ); + return readFileSync(readFilePathUri.fsPath, "utf8"); + } catch (e) { + console.log(e); + return e instanceof Error ? e.message : "Error reading file"; + } + }, + }); + + const questionFile = new DynamicTool({ + name: "readFile", + description: + "Ask something about a file in the file system and this will provide you the snippets and answers. Use this to request information from specific files. Expects a JSON with this type path: string, question: string.", + func: async (relativePath: string) => { + try { + const { path, question } = relativePath as unknown as { + path: string; + question: string; + }; + const readFilePath = path; + const readFilePathUri = vscode.Uri.file( + workspaceFolder + "/" + readFilePath + ); + const content = readFileSync(readFilePathUri.fsPath, "utf8"); + + const docs = await textSplitter.createDocuments([content]); + + const res = await qaChain.call({ + input_documents: docs, + question: question, + }); + return res.text; + } catch (e) { + return e instanceof Error ? e.message : "Error reading file"; + } + }, + }); + + const listFiles = new DynamicTool({ + name: "listFiles", + description: + "Lists files in a directory relative to the project root. Expects the relative path as input and outputs an array of file names and their types.", + func: async (relativePath: string) => { + try { + const files = await vscode.workspace.fs.readDirectory( + vscode.Uri.file(workspaceFolder + "/" + relativePath) + ); + return JSON.stringify( + files.map((f) => `${f[0]} (${vscode.FileType[f[1]]})`) + ); + } catch (e) { + return e instanceof Error ? e.message : "Error listing files"; + } + }, + }); + + const createFile = new DynamicTool({ + name: "createFile", + description: + "Creates a new file in the file system. Expects the relative path as input.", + func: async (relativePath: string) => { + try { + const newFileUri = vscode.Uri.file( + workspaceFolder + "/" + relativePath + ); + await vscode.workspace.fs.writeFile(newFileUri, new Uint8Array()); + return `File created: ${relativePath}`; + } catch (e) { + return e instanceof Error ? e.message : "Error creating file"; + } + }, + }); + + const undo = new DynamicTool({ + name: "undo", + description: "Undoes the last action in the active editor.", + func: async () => { + if (!editor) { + return "No active editor"; + } + await vscode.commands.executeCommand("undo"); + return "Undo executed"; + }, + }); + + const redo = new DynamicTool({ + name: "redo", + description: "Redoes the last action in the active editor.", + func: async () => { + if (!editor) { + return "No active editor"; + } + await vscode.commands.executeCommand("redo"); + return "Redo executed"; + }, + }); + + const input = new DynamicTool({ + name: "input", + description: `Inserts text at a specified location in a file. Expects a JSON with this type path: string; insertLine: number; insertColumn: number; parsedText: string;.`, + func: async (arg) => { + try { + const { path, insertLine, insertColumn, parsedText } = + arg as unknown as { + path: string; + insertLine: number; + insertColumn: number; + parsedText: string; + }; + if (!editor) { + throw new Error("No active editor"); + } + const workspaceFolder = + vscode.workspace.workspaceFolders?.[0].uri.fsPath; + const inputFileUri = vscode.Uri.file(workspaceFolder + "/" + path); + let inputDocument: vscode.TextDocument; + try { + inputDocument = await vscode.workspace.openTextDocument(inputFileUri); + } catch (e) { + await vscode.workspace.fs.writeFile(inputFileUri, new Uint8Array()); + inputDocument = await vscode.workspace.openTextDocument(inputFileUri); + } + editor = await vscode.window.showTextDocument(inputDocument); + + editor.selection = new vscode.Selection( + insertLine, + insertColumn, + insertLine, + insertColumn + ); + await editor.edit((editBuilder) => { + if (!editor) { + throw new Error("No active editor"); + } + editBuilder.insert(editor.selection.active, parsedText); + }); + // get 20 lines before and after the cursor + const startLineInput = Math.max(0, editor.selection.active.line - 20); + const endLineInput = Math.min( + editor.document.lineCount - 1, + editor.selection.active.line + parsedText.split("\n").length + 20 + ); + const range = new vscode.Range( + startLineInput, + 0, + endLineInput, + editor.document.lineAt(endLineInput).text.length + ); + const text = editor.document.getText(range); + return text; + } catch (e) { + return e instanceof Error ? e.message : "Error inserting text"; + } + }, + }); + + const select = new DynamicTool({ + name: "select", + description: + "Selects text in the active editor. Use it to confirm ranges. Expects a JSON with this type startLine: number; startColumn: number; endLine: number; endColumn: number; .", + func: async (arg) => { + try { + const { startLine, startColumn, endLine, endColumn } = + arg as unknown as { + startLine: number; + startColumn: number; + endLine: number; + endColumn: number; + }; + if (!editor) { + throw new Error("No active editor"); + } + editor.selection = new vscode.Selection( + startLine, + startColumn, + endLine, + endColumn + ); + const selectedText = editor.document.getText(editor.selection); + return selectedText; + } catch (e) { + return e instanceof Error ? e.message : "Error selecting text"; + } + }, + }); + + const replace = new DynamicTool({ + name: "replace", + description: `Replaces text in a specified range in a file. Use this when you need to edit a file. Expects a JSON with this type path: string; startLine: number; startColumn: number; endLine: number; endColumn: number; newText: string; .`, + func: async (arg) => { + try { + const { path, startLine, startColumn, endLine, endColumn, newText } = + arg as unknown as { + path: string; + startLine: number; + startColumn: number; + endLine: number; + endColumn: number; + newText: string; + }; + const workspaceFolder = + vscode.workspace.workspaceFolders?.[0].uri.fsPath; + const replaceFileUri = vscode.Uri.file(workspaceFolder + "/" + path); + const replaceDocument = await vscode.workspace.openTextDocument( + replaceFileUri + ); + editor = await vscode.window.showTextDocument(replaceDocument); + await editor.edit((editBuilder) => { + editBuilder.replace( + new vscode.Range(startLine, startColumn, endLine, endColumn), + newText + ); + }); + return "Text replaced"; + } catch (e) { + return e instanceof Error ? e.message : "Error replacing text"; + } + }, + }); + + const copy = new DynamicTool({ + name: "copy", + description: `Copies text in a specified range in a file. Expects a JSON with this type path: string; startLine: number; startColumn: number; endLine: number; endColumn: number; .`, + func: async (arg) => { + try { + const { path, startLine, startColumn, endLine, endColumn } = + arg as unknown as { + path: string; + startLine: number; + startColumn: number; + endLine: number; + endColumn: number; + }; + const workspaceFolder = + vscode.workspace.workspaceFolders?.[0].uri.fsPath; + const copyFileUri = vscode.Uri.file(workspaceFolder + "/" + path); + const copyDocument = await vscode.workspace.openTextDocument( + copyFileUri + ); + const copyRange = new vscode.Range( + startLine, + startColumn, + endLine, + endColumn + ); + const copyText = copyDocument.getText(copyRange); + await vscode.env.clipboard.writeText(copyText); + return "Text copied"; + } catch (e) { + return e instanceof Error ? e.message : "Error copying text"; + } + }, + }); + + const cut = new DynamicTool({ + name: "cut", + description: `Cuts text in a specified range in a file. Expects a JSON with this type path: string; startLine: number; startColumn: number; endLine: number; endColumn: number;.`, + func: async (arg) => { + try { + const { path, startLine, startColumn, endLine, endColumn } = + arg as unknown as { + path: string; + startLine: number; + startColumn: number; + endLine: number; + endColumn: number; + }; + if (!editor) { + throw new Error("No active editor"); + } + const workspaceFolder = + vscode.workspace.workspaceFolders?.[0].uri.fsPath; + const cutFileUri = vscode.Uri.file(workspaceFolder + "/" + path); + const cutDocument = await vscode.workspace.openTextDocument(cutFileUri); + const cutRange = new vscode.Range( + startLine, + startColumn, + endLine, + endColumn + ); + const cutText = cutDocument.getText(cutRange); + await vscode.env.clipboard.writeText(cutText); + await editor.edit((editBuilder) => { + editBuilder.delete(cutRange); + }); + return "Text cut"; + } catch (e) { + return e instanceof Error ? e.message : "Error cutting text"; + } + }, + }); + + const paste = new DynamicTool({ + name: "paste", + description: `Pastes text from the clipboard at a specified location in a file. Expects a JSON with this type path: string; line: number; column: number; .`, + func: async (arg) => { + try { + const { path, line, column } = arg as unknown as { + path: string; + line: number; + column: number; + }; + if (!editor) { + throw new Error("No active editor"); + } + const workspaceFolder = + vscode.workspace.workspaceFolders?.[0].uri.fsPath; + const pasteFileUri = vscode.Uri.file(workspaceFolder + "/" + path); + const pasteDocument = await vscode.workspace.openTextDocument( + pasteFileUri + ); + const pasteText = await vscode.env.clipboard.readText(); + const pasteRange = new vscode.Range(line, column, line, column); + editor = await vscode.window.showTextDocument(pasteDocument); + await editor.edit((editBuilder) => { + if (!editor) { + throw new Error("No active editor"); + } + editBuilder.insert(pasteRange.start, pasteText); + }); + return "Text pasted"; + } catch (e) { + return e instanceof Error ? e.message : "Error pasting text"; + } + }, + }); + + const runInTerminal = new DynamicTool({ + name: "runInTerminal", + description: `Runs a command in the terminal. Expects the command to be executed`, + func: async (terminalCommand) => { + try { + // Open a confirmation modal in VS Code + const confirmation = await vscode.window.showInformationMessage( + `Allow PromptMate to run "${terminalCommand}" in the terminal?`, + "Allow", + "Cancel" + ); + + if (confirmation !== "Allow") { + return "user cancelled command"; + } + + const output = await new Promise((resolve, reject) => { + exec( + terminalCommand, + { + cwd: workspaceFolder, + }, + (error, stdout, stderr) => { + if (error) { + console.log(`error: ${error.message}`); + resolve(error.message); + return; + } + if (stderr) { + console.log(`stderr: ${stderr}`); + resolve(stderr); + return; + } + resolve(stdout); + } + ); + }); + + return output as string; + } catch (e) { + return e instanceof Error ? e.message : "Error running command"; + } + }, + }); + + const getSyntaxErrors = new DynamicTool({ + name: "getSyntaxErrors", + description: `Gets syntax errors in a file. ALWAYS run this after code changes. Expects the relative path as input.`, + func: async (path) => { + try { + const workspaceFolder = + vscode.workspace.workspaceFolders?.[0].uri.fsPath; + const fileUri = vscode.Uri.file(workspaceFolder + "/" + path); + const diagnostics = vscode.languages.getDiagnostics(fileUri); + const errors = diagnostics.filter( + (diagnostic) => + diagnostic.severity === vscode.DiagnosticSeverity.Error + ); + const errorMessages = errors.map((error) => { + const range = error.range; + const line = range.start.line; + const column = range.start.character; + const message = error.message; + return { + line, + column, + message, + }; + }); + return JSON.stringify(errorMessages); + } catch (e) { + return e instanceof Error ? e.message : "Error getting syntax errors"; + } + }, + }); + + const autonomousTools = [ + createFile, + undo, + redo, + input, + replace, + copy, + cut, + paste, + runInTerminal, + getSyntaxErrors, + readFile + ]; + + const readOnlyTools = [ + readFileSummary, + readFile, + listFiles, + select, + getSyntaxErrors, + browser, + questionFile, + ...extraTools, + ]; + + if (!autonomous) { + return readOnlyTools; + } + + return [...autonomousTools, ...readOnlyTools]; +} diff --git a/tsconfig.json b/tsconfig.json index 965a7b4..ff90606 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,16 +1,15 @@ { - "compilerOptions": { - "module": "commonjs", - "target": "ES2020", - "lib": [ - "ES2020" - ], - "sourceMap": true, - "rootDir": "src", - "strict": true /* enable all strict type-checking options */ - /* Additional Checks */ - // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ - // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ - // "noUnusedParameters": true, /* Report errors on unused parameters. */ - } + "compilerOptions": { + "module": "commonjs", + "target": "ESNext", + "lib": ["ESNext"], + "sourceMap": true, + "rootDir": "src", + "strict": true /* enable all strict type-checking options */ + /* Additional Checks */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + }, + "include": ["global.d.ts", "src/**/*"] } diff --git a/webpack.config.js b/webpack.config.js index 35ee52f..d287b4b 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,7 +2,12 @@ 'use strict'; -const path = require('path'); +import path from 'path'; +import { fileURLToPath } from 'url'; +// eslint-disable-next-line @typescript-eslint/naming-convention +const __filename = fileURLToPath(import.meta.url); +// eslint-disable-next-line @typescript-eslint/naming-convention +const __dirname = path.dirname(__filename); //@ts-check /** @typedef {import('webpack').Configuration} WebpackConfig **/ @@ -16,7 +21,7 @@ const extensionConfig = { output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/ path: path.resolve(__dirname, 'dist'), - filename: 'extension.js', + filename: 'extension.cjs', libraryTarget: 'commonjs2' }, externals: { @@ -49,4 +54,4 @@ const extensionConfig = { level: "log", // enables logging required for problem matchers }, }; -module.exports = [ extensionConfig ]; +export default [ extensionConfig ];