diff --git a/README.md b/README.md index bdc20a9..4584461 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Alexible, scalable and customizable agent to do your bidding. - Retrievable memory and document store - Serverless artchitecture, deployable in minutes at scale with Cloudflare and Supabase - Multi-agent and room support -- Reflection and summarization +- Summarization and summarization - Goal-directed behavior ## Installation diff --git a/jest.config.js b/jest.config.js index f759bf7..1e7d5ca 100644 --- a/jest.config.js +++ b/jest.config.js @@ -1,12 +1,12 @@ /** @type {import('ts-jest').JestConfigWithTsJest} */ export default { - preset: 'ts-jest', - testEnvironment: 'node', - rootDir: './src', - testMatch: ['**/*.test.ts'], + preset: "ts-jest", + testEnvironment: "node", + rootDir: "./src", + testMatch: ["**/*.test.ts"], globals: { __DEV__: true, __TEST__: true, - __VERSION__: '0.0.1' - } -} + __VERSION__: "0.0.1", + }, +}; diff --git a/package-lock.json b/package-lock.json index ac53e71..2ed01ab 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,21 +1,23 @@ { "name": "bgent", - "version": "0.0.4", + "version": "0.0.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "bgent", - "version": "0.0.4", + "version": "0.0.6", "license": "MIT", "dependencies": { "@rollup/plugin-json": "^6.1.0", "@supabase/supabase-js": "^2.39.3", "@tsndr/cloudflare-worker-jwt": "^2.2.1", + "@typescript-eslint/eslint-plugin": "^7.0.1", "dotenv": "^16.4.4", "figlet": "^1.7.0", "inquirer": "^9.2.14", - "ts-node": "^10.9.2" + "ts-node": "^10.9.2", + "unique-names-generator": "^4.7.1" }, "bin": { "bgent": "scripts/shell.mjs" @@ -28,7 +30,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/jest": "^27.5.2", "@types/node": "20.9.4", - "@typescript-eslint/parser": "^6.21.0", + "@typescript-eslint/parser": "^7.0.1", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", @@ -50,7 +52,6 @@ "version": "1.2.6", "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -1210,7 +1211,6 @@ "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", - "dev": true, "dependencies": { "eslint-visitor-keys": "^3.3.0" }, @@ -1225,7 +1225,6 @@ "version": "4.10.0", "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.0.tgz", "integrity": "sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA==", - "dev": true, "engines": { "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } @@ -1234,7 +1233,6 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", - "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -1257,7 +1255,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1267,7 +1264,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1279,7 +1275,6 @@ "version": "8.56.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.56.0.tgz", "integrity": "sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -1297,7 +1292,6 @@ "version": "0.11.14", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", - "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.2", "debug": "^4.3.1", @@ -1311,7 +1305,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -1321,7 +1314,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -1333,7 +1325,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", - "dev": true, "engines": { "node": ">=12.22" }, @@ -1345,8 +1336,7 @@ "node_modules/@humanwhocodes/object-schema": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.2.tgz", - "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==", - "dev": true + "integrity": "sha512-6EwiSjwWYP7pTckG6I5eyFANjPhmPjUX9JRLUSfNPC7FX7zK9gyZAfUEaECL6ALTpGX5AjnBq3C9XmVWPitNpw==" }, "node_modules/@isaacs/cliui": { "version": "8.0.2", @@ -2070,7 +2060,6 @@ "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -2083,7 +2072,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, "engines": { "node": ">= 8" } @@ -2092,7 +2080,6 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -2465,6 +2452,11 @@ "pretty-format": "^27.0.0" } }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==" + }, "node_modules/@types/node": { "version": "20.9.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.4.tgz", @@ -2493,6 +2485,11 @@ "integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==", "dev": true }, + "node_modules/@types/semver": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.7.tgz", + "integrity": "sha512-/wdoPq1QqkSj9/QOeKkFquEuPzQbHTWAMPH/PaUMB+JuR31lXhlWXRZ52IpfDYVlDOUBvX09uBrPwxGT1hjNBg==" + }, "node_modules/@types/stack-utils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", @@ -2522,16 +2519,49 @@ "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", "dev": true }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-7.0.1.tgz", + "integrity": "sha512-OLvgeBv3vXlnnJGIAgCLYKjgMEU+wBGj07MQ/nxAaON+3mLzX7mJbhRYrVGiVvFiXtwFlkcBa/TtmglHy0UbzQ==", + "dependencies": { + "@eslint-community/regexpp": "^4.5.1", + "@typescript-eslint/scope-manager": "7.0.1", + "@typescript-eslint/type-utils": "7.0.1", + "@typescript-eslint/utils": "7.0.1", + "@typescript-eslint/visitor-keys": "7.0.1", + "debug": "^4.3.4", + "graphemer": "^1.4.0", + "ignore": "^5.2.4", + "natural-compare": "^1.4.0", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^7.0.0", + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@typescript-eslint/parser": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz", - "integrity": "sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==", - "dev": true, + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-7.0.1.tgz", + "integrity": "sha512-8GcRRZNzaHxKzBPU3tKtFNing571/GwPBeCvmAUw0yBtfE2XVd0zFKJIMSWkHJcPQi0ekxjIts6L/rrZq5cxGQ==", "dependencies": { - "@typescript-eslint/scope-manager": "6.21.0", - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/typescript-estree": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/scope-manager": "7.0.1", + "@typescript-eslint/types": "7.0.1", + "@typescript-eslint/typescript-estree": "7.0.1", + "@typescript-eslint/visitor-keys": "7.0.1", "debug": "^4.3.4" }, "engines": { @@ -2542,7 +2572,7 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^8.56.0" }, "peerDependenciesMeta": { "typescript": { @@ -2551,13 +2581,12 @@ } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", - "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", - "dev": true, + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-7.0.1.tgz", + "integrity": "sha512-v7/T7As10g3bcWOOPAcbnMDuvctHzCFYCG/8R4bK4iYzdFqsZTbXGln0cZNVcwQcwewsYU2BJLay8j0/4zOk4w==", "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0" + "@typescript-eslint/types": "7.0.1", + "@typescript-eslint/visitor-keys": "7.0.1" }, "engines": { "node": "^16.0.0 || >=18.0.0" @@ -2567,11 +2596,36 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/type-utils": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-7.0.1.tgz", + "integrity": "sha512-YtT9UcstTG5Yqy4xtLiClm1ZpM/pWVGFnkAa90UfdkkZsR1eP2mR/1jbHeYp8Ay1l1JHPyGvoUYR6o3On5Nhmw==", + "dependencies": { + "@typescript-eslint/typescript-estree": "7.0.1", + "@typescript-eslint/utils": "7.0.1", + "debug": "^4.3.4", + "ts-api-utils": "^1.0.1" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@typescript-eslint/types": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", - "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", - "dev": true, + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.0.1.tgz", + "integrity": "sha512-uJDfmirz4FHib6ENju/7cz9SdMSkeVvJDK3VcMFvf/hAShg8C74FW+06MaQPODHfDJp/z/zHfgawIJRjlu0RLg==", "engines": { "node": "^16.0.0 || >=18.0.0" }, @@ -2581,13 +2635,12 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", - "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", - "dev": true, + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-7.0.1.tgz", + "integrity": "sha512-SO9wHb6ph0/FN5OJxH4MiPscGah5wjOd0RRpaLvuBv9g8565Fgu0uMySFEPqwPHiQU90yzJ2FjRYKGrAhS1xig==", "dependencies": { - "@typescript-eslint/types": "6.21.0", - "@typescript-eslint/visitor-keys": "6.21.0", + "@typescript-eslint/types": "7.0.1", + "@typescript-eslint/visitor-keys": "7.0.1", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -2608,13 +2661,36 @@ } } }, + "node_modules/@typescript-eslint/utils": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-7.0.1.tgz", + "integrity": "sha512-oe4his30JgPbnv+9Vef1h48jm0S6ft4mNwi9wj7bX10joGn07QRfqIqFHoMiajrtoU88cIhXf8ahwgrcbNLgPA==", + "dependencies": { + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "7.0.1", + "@typescript-eslint/types": "7.0.1", + "@typescript-eslint/typescript-estree": "7.0.1", + "semver": "^7.5.4" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^8.56.0" + } + }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "6.21.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", - "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", - "dev": true, + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-7.0.1.tgz", + "integrity": "sha512-hwAgrOyk++RTXrP4KzCg7zB2U0xt7RUU0ZdMSCsqF3eKUwkdXUMyTb0qdCuji7VIbcpG62kKTU9M1J1c9UpFBw==", "dependencies": { - "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/types": "7.0.1", "eslint-visitor-keys": "^3.4.1" }, "engines": { @@ -2628,8 +2704,7 @@ "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", - "dev": true + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" }, "node_modules/acorn": { "version": "8.11.3", @@ -2646,7 +2721,6 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } @@ -2663,7 +2737,6 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2743,8 +2816,7 @@ "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-buffer-byte-length": { "version": "1.0.1", @@ -2766,7 +2838,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, "engines": { "node": ">=8" } @@ -2949,8 +3020,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/base64-js": { "version": "1.5.1", @@ -3000,7 +3070,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -3009,7 +3078,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -3133,7 +3201,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true, "engines": { "node": ">=6" } @@ -3433,8 +3500,7 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", - "dev": true + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, "node_modules/convert-source-map": { "version": "2.0.0", @@ -3497,7 +3563,6 @@ "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -3517,7 +3582,6 @@ "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dev": true, "dependencies": { "ms": "2.1.2" }, @@ -3547,8 +3611,7 @@ "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", - "dev": true + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" }, "node_modules/deepmerge": { "version": "4.3.1", @@ -3633,7 +3696,6 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", - "dev": true, "dependencies": { "path-type": "^4.0.0" }, @@ -3645,7 +3707,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "dependencies": { "esutils": "^2.0.2" }, @@ -3858,7 +3919,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -3870,7 +3930,6 @@ "version": "8.56.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.56.0.tgz", "integrity": "sha512-Go19xM6T9puCOWntie1/P997aXxFsOi37JIHRWI514Hc6ZnaHGKY9xFhrU65RT6CcBEzZoGG1e6Nq+DT04ZtZQ==", - "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -3967,7 +4026,6 @@ "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", - "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -3983,7 +4041,6 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -3995,7 +4052,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4005,7 +4061,6 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4021,7 +4076,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4033,7 +4087,6 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -4063,7 +4116,6 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", - "dev": true, "dependencies": { "estraverse": "^5.1.0" }, @@ -4075,7 +4127,6 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "dev": true, "dependencies": { "estraverse": "^5.2.0" }, @@ -4087,7 +4138,6 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, "engines": { "node": ">=4.0" } @@ -4101,7 +4151,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -4290,8 +4339,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-diff": { "version": "1.3.0", @@ -4303,7 +4351,6 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", - "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -4319,7 +4366,6 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -4330,20 +4376,17 @@ "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", - "dev": true + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" }, "node_modules/fastq": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", - "dev": true, "dependencies": { "reusify": "^1.0.4" } @@ -4394,7 +4437,6 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "dev": true, "dependencies": { "flat-cache": "^3.0.4" }, @@ -4406,7 +4448,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", - "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -4418,7 +4459,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -4434,7 +4474,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", - "dev": true, "dependencies": { "flatted": "^3.2.9", "keyv": "^4.5.3", @@ -4448,7 +4487,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -4458,7 +4496,6 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -4478,7 +4515,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -4490,7 +4526,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -4504,8 +4539,7 @@ "node_modules/flatted": { "version": "3.2.9", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.9.tgz", - "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", - "dev": true + "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==" }, "node_modules/for-each": { "version": "0.3.3", @@ -4547,8 +4581,7 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", - "dev": true + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, "node_modules/fsevents": { "version": "2.3.3", @@ -4718,7 +4751,6 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -4748,7 +4780,6 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", - "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -4778,7 +4809,6 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -4814,8 +4844,7 @@ "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==" }, "node_modules/has-bigints": { "version": "1.0.2", @@ -4948,7 +4977,6 @@ "version": "5.3.1", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", - "dev": true, "engines": { "node": ">= 4" } @@ -4957,7 +4985,6 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dev": true, "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -4992,7 +5019,6 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", - "dev": true, "engines": { "node": ">=0.8.19" } @@ -5001,7 +5027,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -5233,7 +5258,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -5263,7 +5287,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "dependencies": { "is-extglob": "^2.1.1" }, @@ -5301,7 +5324,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "engines": { "node": ">=0.12.0" } @@ -5325,7 +5347,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", - "dev": true, "engines": { "node": ">=8" } @@ -5456,8 +5477,7 @@ "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", - "dev": true + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" }, "node_modules/istanbul-lib-coverage": { "version": "3.2.2", @@ -6832,7 +6852,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, "dependencies": { "argparse": "^2.0.1" }, @@ -6855,8 +6874,7 @@ "node_modules/json-buffer": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==" }, "node_modules/json-parse-better-errors": { "version": "1.0.2", @@ -6873,14 +6891,12 @@ "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", - "dev": true + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, "node_modules/json5": { "version": "2.2.3", @@ -6898,7 +6914,6 @@ "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", - "dev": true, "dependencies": { "json-buffer": "3.0.1" } @@ -6925,7 +6940,6 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -7168,7 +7182,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, "dependencies": { "p-locate": "^5.0.0" }, @@ -7193,8 +7206,7 @@ "node_modules/lodash.merge": { "version": "4.6.2", "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", - "dev": true + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, "node_modules/log-symbols": { "version": "4.1.0", @@ -7411,7 +7423,6 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, "engines": { "node": ">= 8" } @@ -7420,7 +7431,6 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -7479,7 +7489,6 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -7502,8 +7511,7 @@ "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, "node_modules/mustache": { "version": "4.2.0", @@ -7543,8 +7551,7 @@ "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", - "dev": true + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" }, "node_modules/nice-try": { "version": "1.0.5", @@ -7852,7 +7859,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "dependencies": { "wrappy": "1" } @@ -7875,7 +7881,6 @@ "version": "0.9.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", - "dev": true, "dependencies": { "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", @@ -7960,7 +7965,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, "dependencies": { "yocto-queue": "^0.1.0" }, @@ -7975,7 +7979,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, "dependencies": { "p-limit": "^3.0.2" }, @@ -7999,7 +8002,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "dependencies": { "callsites": "^3.0.0" }, @@ -8029,7 +8031,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true, "engines": { "node": ">=8" } @@ -8038,7 +8039,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -8047,7 +8047,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "engines": { "node": ">=8" } @@ -8093,7 +8092,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true, "engines": { "node": ">=8" } @@ -8213,7 +8211,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true, "engines": { "node": ">= 0.8.0" } @@ -8294,7 +8291,6 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", - "dev": true, "engines": { "node": ">=6" } @@ -8319,7 +8315,6 @@ "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, "funding": [ { "type": "github", @@ -8470,7 +8465,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true, "engines": { "node": ">=4" } @@ -8504,7 +8498,6 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, "engines": { "iojs": ">=1.0.0", "node": ">=0.10.0" @@ -8664,7 +8657,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, "funding": [ { "type": "github", @@ -8767,7 +8759,6 @@ "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", "integrity": "sha512-EnwXhrlwXMk9gKu5/flx5sv/an57AkRplG3hTK68W7FRDN+k+OWBj65M7719OkA82XLBxrcX0KSHj+X5COhOVg==", - "dev": true, "dependencies": { "lru-cache": "^6.0.0" }, @@ -8782,7 +8773,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "dev": true, "dependencies": { "yallist": "^4.0.0" }, @@ -8793,8 +8783,7 @@ "node_modules/semver/node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" }, "node_modules/serialize-javascript": { "version": "4.0.0", @@ -8839,7 +8828,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "dependencies": { "shebang-regex": "^3.0.0" }, @@ -8851,7 +8839,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "engines": { "node": ">=8" } @@ -8898,7 +8885,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, "engines": { "node": ">=8" } @@ -9248,7 +9234,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", - "dev": true, "engines": { "node": ">=8" }, @@ -9388,8 +9373,7 @@ "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", - "dev": true + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" }, "node_modules/tmp": { "version": "0.0.33", @@ -9421,7 +9405,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -9438,7 +9421,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.2.1.tgz", "integrity": "sha512-RIYA36cJn2WiH9Hy77hdF9r7oEwxAtB/TS9/S4Qd90Ap4z5FSiin5zEiTL44OII1Y3IIlEvxwxFUVgrHSZ/UpA==", - "dev": true, "engines": { "node": ">=16" }, @@ -9540,7 +9522,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, "dependencies": { "prelude-ls": "^1.2.1" }, @@ -9561,7 +9542,6 @@ "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, "engines": { "node": ">=10" }, @@ -9678,6 +9658,14 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" }, + "node_modules/unique-names-generator": { + "version": "4.7.1", + "resolved": "https://registry.npmjs.org/unique-names-generator/-/unique-names-generator-4.7.1.tgz", + "integrity": "sha512-lMx9dX+KRmG8sq6gulYYpKWZc9RlGsgBR6aoO8Qsm3qvkSJ+3rAymr+TnV8EDMrIrwuFJ4kruzMWM/OpYzPoow==", + "engines": { + "node": ">=8" + } + }, "node_modules/update-browserslist-db": { "version": "1.0.13", "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz", @@ -9712,7 +9700,6 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -9786,7 +9773,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "dependencies": { "isexe": "^2.0.0" }, @@ -9998,8 +9984,7 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, "node_modules/write-file-atomic": { "version": "4.0.2", @@ -10132,7 +10117,6 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", - "dev": true, "engines": { "node": ">=10" }, diff --git a/package.json b/package.json index 10f07b5..3ed7351 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "@rollup/plugin-typescript": "^11.1.6", "@types/jest": "^27.5.2", "@types/node": "20.9.4", - "@typescript-eslint/parser": "^6.21.0", + "@typescript-eslint/parser": "^7.0.1", "eslint": "^8.56.0", "eslint-config-prettier": "^9.1.0", "eslint-plugin-prettier": "^5.1.3", @@ -57,9 +57,11 @@ "@rollup/plugin-json": "^6.1.0", "@supabase/supabase-js": "^2.39.3", "@tsndr/cloudflare-worker-jwt": "^2.2.1", + "@typescript-eslint/eslint-plugin": "^7.0.1", "dotenv": "^16.4.4", "figlet": "^1.7.0", "inquirer": "^9.2.14", - "ts-node": "^10.9.2" + "ts-node": "^10.9.2", + "unique-names-generator": "^4.7.1" } } diff --git a/scripts/concat.mjs b/scripts/concat.mjs index ef6a8e8..40fc3ff 100644 --- a/scripts/concat.mjs +++ b/scripts/concat.mjs @@ -5,7 +5,7 @@ import { fileURLToPath } from 'url' const instructions = 'The above code was taken from my codebase at https://github.com/lalalune/bgent. You are writing tests and documentation for my codebase. Please use the above code as a reference. Tests should be written with Jest and Typescript. Do not use mocks or stubs. Keep it very simple and straightforward.' // Patterns to ignore -const ignorePatterns = ['messageExamples.ts', 'agents', 'goal', 'goals', 'utils', 'logger', 'index', 'data', 'constants', 'templates', 'worker'] +const ignorePatterns = ['actionExamples.ts', 'agents', 'goal', 'goals', 'utils', 'logger', 'index', 'data', 'constants', 'templates', 'worker'] // __dirname is not defined in ES module scope, so we need to create it const __filename = fileURLToPath(import.meta.url) diff --git a/src/agents/cj/evaluators/__tests__/profile.test.ts b/src/agents/cj/evaluators/__tests__/profile.test.ts index 056ab95..97474de 100644 --- a/src/agents/cj/evaluators/__tests__/profile.test.ts +++ b/src/agents/cj/evaluators/__tests__/profile.test.ts @@ -162,7 +162,10 @@ describe("User Profile", () => { expect(result.toLowerCase().includes("francisco")).toBe(true); - expect(result.toLowerCase().includes("startup") || result.toLowerCase().includes("programmer")).toBe(true); + expect( + result.toLowerCase().includes("startup") || + result.toLowerCase().includes("programmer"), + ).toBe(true); const descriptions = await runtime.descriptionManager.getMemoriesByIds({ userIds: [message.senderId, message.agentId] as UUID[], diff --git a/src/agents/cj/evaluators/details.ts b/src/agents/cj/evaluators/details.ts index 9c0bb94..7f25062 100644 --- a/src/agents/cj/evaluators/details.ts +++ b/src/agents/cj/evaluators/details.ts @@ -59,7 +59,7 @@ const handler = async (runtime: BgentRuntime, message: Message) => { const { name, age, location, gender } = responseData; - console.log('responseData', responseData) + console.log("responseData", responseData); const response = await runtime.supabase .from("accounts") diff --git a/src/agents/cj/evaluators/profile.ts b/src/agents/cj/evaluators/profile.ts index 99db508..0d7c169 100644 --- a/src/agents/cj/evaluators/profile.ts +++ b/src/agents/cj/evaluators/profile.ts @@ -225,9 +225,5 @@ export default { condition: "The user has revealed new personal information in the conversation which is important to update in their profile.", handler, - examples: [ - `{ - - }`, - ], + examples: [], } as Evaluator; diff --git a/src/agents/cj/index.ts b/src/agents/cj/index.ts index d66b983..55d143c 100644 --- a/src/agents/cj/index.ts +++ b/src/agents/cj/index.ts @@ -1,14 +1,43 @@ import { createClient, type SupabaseClient } from "@supabase/supabase-js"; import jwt from "@tsndr/cloudflare-worker-jwt"; import { type UUID } from "crypto"; +import { DefaultActions } from "../../lib/actions"; import logger from "../../lib/logger"; import { BgentRuntime } from "../../lib/runtime"; -import { type Content, type Message, type State } from "../../lib/types"; -import { shouldSkipMessage } from "../../lib/utils"; +import { + type Content, + type Memory, + type Message, + type State, +} from "../../lib/types"; import actions from "./actions"; import evaluators from "./evaluators"; import flavor from "./flavor"; +export function shouldSkipMessage(state: State, agentId: string): boolean { + if (state.recentMessagesData && state.recentMessagesData.length > 2) { + const currentMessages = state.recentMessagesData ?? []; + const lastThreeMessages = currentMessages.slice(-3); + const lastThreeMessagesFromAgent = lastThreeMessages.filter( + (message: Memory) => message.user_id === agentId, + ); + if (lastThreeMessagesFromAgent.length === 3) { + return true; + } + + const lastTwoMessagesFromAgent = lastThreeMessagesFromAgent.slice(-2); + const lastTwoMessagesFromAgentWithWaitAction = + lastTwoMessagesFromAgent.filter( + (message: Memory) => + (message.content as Content).action === DefaultActions.WAIT, + ); + if (lastTwoMessagesFromAgentWithWaitAction.length === 2) { + return true; + } + } + return false; +} + const onMessage = async ( message: Message, runtime: BgentRuntime, diff --git a/src/lib/__tests__/actions.test.ts b/src/lib/__tests__/actions.test.ts index ba16a71..de157e5 100644 --- a/src/lib/__tests__/actions.test.ts +++ b/src/lib/__tests__/actions.test.ts @@ -7,6 +7,7 @@ import { getRelationship } from "../relationships"; import { type BgentRuntime } from "../runtime"; import { Content, type Message } from "../types"; import { GetTellMeAboutYourselfConversationTroll1 } from "../../test/data"; +import { DefaultActions } from "../actions"; dotenv.config(); @@ -38,7 +39,7 @@ describe("User Profile", () => { }); async function cleanup() { - await runtime.reflectionManager.removeAllMemoriesByUserIds([ + await runtime.summarizationManager.removeAllMemoriesByUserIds([ user?.id as UUID, zeroUuid, ]); @@ -79,22 +80,28 @@ describe("User Profile", () => { senderId: user.id as UUID, agentId: zeroUuid, userIds: [user?.id as UUID, zeroUuid], - content: '', - room_id: room_id as UUID - } + content: "", + room_id: room_id as UUID, + }; - await populateMemories([ - GetTellMeAboutYourselfConversationTroll1 - ]); + await populateMemories([GetTellMeAboutYourselfConversationTroll1]); - await runtime.handleRequest(message); + const response = await runtime.handleRequest(message); const state = await runtime.composeState(message); - console.log('state.recentMessagesData', state.recentMessagesData) + console.log( + "*** recentMessagesData", + state.recentMessagesData.map((m) => m.content), + ); + + console.log("*** response", response); + + const lastMessage = state.recentMessagesData[0]; - const lastMessage = state.recentMessagesData[state.recentMessagesData.length - 1] - expect((lastMessage.content as Content).action).toBe('ignore') + console.log("*** lastMessage", lastMessage.content); + + expect((lastMessage.content as Content).action).toBe(DefaultActions.IGNORE); }, 60000); test("Action handler test: continue", async () => { @@ -123,9 +130,7 @@ describe("User Profile", () => { // test an example action being included in the template - // load in three continues in a row and verify that they should not continue - }, 60000); test("Action handler test: wait", async () => { @@ -137,10 +142,9 @@ describe("User Profile", () => { // room_id: room_id as UUID // } - // TODO: test action handler with a message that should wait for a response + // TODO: test action handler with a message that should wait for a response // evaluate that the response action is a wait - await populateMemories([ // continue conversation 1 (should wait) ]); diff --git a/src/lib/__tests__/evaluation.test.ts b/src/lib/__tests__/evaluation.test.ts index 15f0b5a..eeb8300 100644 --- a/src/lib/__tests__/evaluation.test.ts +++ b/src/lib/__tests__/evaluation.test.ts @@ -4,81 +4,81 @@ import { type Message } from "../types"; import { createRuntime } from "../../test/createRuntime"; import { type UUID } from "crypto"; -describe('Evaluation Process', () => { - let runtime: BgentRuntime; - let user: User; - const zeroUuid = '00000000-0000-0000-0000-000000000000'; +describe("Evaluation Process", () => { + let runtime: BgentRuntime; + let user: User; + const zeroUuid = "00000000-0000-0000-0000-000000000000"; - beforeAll(async () => { - const setup = await createRuntime(); - runtime = setup.runtime; - user = setup.session.user; + beforeAll(async () => { + const setup = await createRuntime(); + runtime = setup.runtime; + user = setup.session.user; - // Assuming the evaluator 'reflect' is already registered in the runtime setup - }); - - test('Evaluation Injection - Evaluator Creates Memory', async () => { - const message: Message = { - senderId: user.id as UUID, - agentId: zeroUuid, - userIds: [user?.id as UUID, zeroUuid], - content: 'Trigger evaluator content', - room_id: zeroUuid - }; + // Assuming the evaluator 'summary' is already registered in the runtime setup + }); - await runtime.handleRequest(message); + test("Evaluation Injection - Evaluator Creates Memory", async () => { + const message: Message = { + senderId: user.id as UUID, + agentId: zeroUuid, + userIds: [user?.id as UUID, zeroUuid], + content: "Trigger evaluator content", + room_id: zeroUuid, + }; - // Assuming the 'reflect' evaluator tags the memories it creates with 'reflection' - const memories = await runtime.reflectionManager.getMemoriesByIds({ - userIds: [user.id as UUID, zeroUuid], - count: 1 - }); + await runtime.handleRequest(message); - // Expect at least one memory to be created with the 'reflection' tag - expect(memories.length).toBeGreaterThan(0); + // Assuming the 'summary' evaluator tags the memories it creates with 'summarization' + const memories = await runtime.summarizationManager.getMemoriesByIds({ + userIds: [user.id as UUID, zeroUuid], + count: 1, }); - test('Evaluator Not Running if No Evaluation Handlers are True', async () => { - const message: Message = { - senderId: user?.id as UUID, - agentId: zeroUuid, - userIds: [user?.id as UUID, zeroUuid], - content: 'Non-triggering content', - room_id: zeroUuid - }; + // Expect at least one memory to be created with the 'summarization' tag + expect(memories.length).toBeGreaterThan(0); + }); - await runtime.handleRequest(message); + test("Evaluator Not Running if No Evaluation Handlers are True", async () => { + const message: Message = { + senderId: user?.id as UUID, + agentId: zeroUuid, + userIds: [user?.id as UUID, zeroUuid], + content: "Non-triggering content", + room_id: zeroUuid, + }; - // Assuming the 'reflect' evaluator tags the memories it creates with 'reflection' - const memories = await runtime.reflectionManager.getMemoriesByIds({ - userIds: [user.id as UUID, zeroUuid], - count: 10 - }); + await runtime.handleRequest(message); - // Assuming the previous test ran and created exactly one memory - // Expect the number of memories to remain unchanged - expect(memories.length).toBe(1); + // Assuming the 'summary' evaluator tags the memories it creates with 'summarization' + const memories = await runtime.summarizationManager.getMemoriesByIds({ + userIds: [user.id as UUID, zeroUuid], + count: 10, }); - test('Evaluation Handling and Response - Evaluator Updates Memory', async () => { - const message: Message = { - senderId: user.id as UUID, - agentId: zeroUuid, - userIds: [user.id as UUID, zeroUuid], - content: 'Content that leads to a specific evaluator response', - room_id: zeroUuid - }; + // Assuming the previous test ran and created exactly one memory + // Expect the number of memories to remain unchanged + expect(memories.length).toBe(1); + }); - await runtime.handleRequest(message); + test("Evaluation Handling and Response - Evaluator Updates Memory", async () => { + const message: Message = { + senderId: user.id as UUID, + agentId: zeroUuid, + userIds: [user.id as UUID, zeroUuid], + content: "Content that leads to a specific evaluator response", + room_id: zeroUuid, + }; - // Assuming the 'reflect' evaluator updates the 'content' of memories it processes - // Fetch the updated memory - const memories = await runtime.reflectionManager.getMemoriesByIds({ - userIds: [user.id as UUID, zeroUuid], - count: 1 - }); - - // Expect the updated memory to contain specific content - expect(memories[0].content).toContain('specific content'); + await runtime.handleRequest(message); + + // Assuming the 'summary' evaluator updates the 'content' of memories it processes + // Fetch the updated memory + const memories = await runtime.summarizationManager.getMemoriesByIds({ + userIds: [user.id as UUID, zeroUuid], + count: 1, }); + + // Expect the updated memory to contain specific content + expect(memories[0].content).toContain("specific content"); + }); }); diff --git a/src/lib/__tests__/messages.test.ts b/src/lib/__tests__/messages.test.ts index 734370b..44ef9f4 100644 --- a/src/lib/__tests__/messages.test.ts +++ b/src/lib/__tests__/messages.test.ts @@ -4,12 +4,11 @@ import { createRuntime } from "../../test/createRuntime"; import { formatMessageActors, formatMessages, - formatReflections, getMessageActors, - getRandomMessageExamples, } from "../messages"; import { type BgentRuntime } from "../runtime"; -import { type Content, type Actor, type Memory } from "../types"; +import { type Actor, type Content, type Memory } from "../types"; +import { formatSummarizations } from "../evaluators/summarization"; describe("Messages Library", () => { let runtime: BgentRuntime, user: User, actors: Actor[]; @@ -43,13 +42,6 @@ describe("Messages Library", () => { expect(formattedActors).toContain(actor.name); }); }); - - - test("getRandomMessageExamples should return a specified number of random message examples", () => { - const examples = getRandomMessageExamples(3); - console.log("*** examples", examples); - expect(examples.split("\n\n").length).toBe(3); - }); test("formatMessages should format messages into a readable string", async () => { const messages: Memory[] = [ @@ -75,8 +67,8 @@ describe("Messages Library", () => { }); }); - test("formatReflections should format reflections into a readable string", async () => { - const reflections: Memory[] = [ + test("formatSummarizations should format summarizations into a readable string", async () => { + const summarizations: Memory[] = [ { content: "Reflecting on the day", user_id: user.id as UUID, @@ -90,9 +82,9 @@ describe("Messages Library", () => { room_id: "00000000-0000-0000-0000-000000000000room", }, ]; - const formattedReflections = formatReflections(reflections); - reflections.forEach((reflection) => { - expect(formattedReflections).toContain(reflection.content); + const formattedSummarizations = formatSummarizations(summarizations); + summarizations.forEach((summarization) => { + expect(formattedSummarizations).toContain(summarization.content); }); }); }); diff --git a/src/lib/__tests__/relationships.test.ts b/src/lib/__tests__/relationships.test.ts index 431ca65..e3655b0 100644 --- a/src/lib/__tests__/relationships.test.ts +++ b/src/lib/__tests__/relationships.test.ts @@ -1,73 +1,86 @@ -import { type User } from '@supabase/supabase-js'; -import { type UUID } from 'crypto'; -import dotenv from 'dotenv'; -import { createRuntime } from '../../test/createRuntime'; // Adjust the import path as needed +import { type User } from "@supabase/supabase-js"; +import { type UUID } from "crypto"; +import dotenv from "dotenv"; +import { createRuntime } from "../../test/createRuntime"; // Adjust the import path as needed import { - createRelationship, - getRelationship, - getRelationships -} from '../relationships'; // Adjust the import path as needed -import { BgentRuntime } from '../runtime'; + createRelationship, + getRelationship, + getRelationships, +} from "../relationships"; // Adjust the import path as needed +import { BgentRuntime } from "../runtime"; dotenv.config(); const zeroUuid = "00000000-0000-0000-0000-000000000000"; -describe('Relationships Module', () => { - let runtime: BgentRuntime; - let user: User; +describe("Relationships Module", () => { + let runtime: BgentRuntime; + let user: User; - beforeAll(async () => { - const setup = await createRuntime(); - runtime = setup.runtime; - user = setup.session.user; - }); - - test('createRelationship creates a new relationship', async () => { - const userA = user?.id as UUID; - const userB = zeroUuid; + beforeAll(async () => { + const setup = await createRuntime(); + runtime = setup.runtime; + user = setup.session.user; + }); - const relationship = await createRelationship({ supabase: runtime.supabase, userA, userB }); + test("createRelationship creates a new relationship", async () => { + const userA = user?.id as UUID; + const userB = zeroUuid; - expect(relationship).toBe(true); + const relationship = await createRelationship({ + supabase: runtime.supabase, + userA, + userB, }); - test('getRelationship retrieves an existing relationship', async () => { - const userA = user?.id as UUID; - const userB = zeroUuid; - - await createRelationship({ supabase: runtime.supabase, userA, userB }); + expect(relationship).toBe(true); + }); - const relationship = await getRelationship({ supabase: runtime.supabase, userA, userB }); - expect(relationship).toBeDefined(); - expect(relationship.user_a).toBe(userA); - expect(relationship.user_b).toBe(userB); - }); - - test('getRelationships retrieves all relationships for a user', async () => { - const userA = user?.id as UUID; - const userB = zeroUuid; + test("getRelationship retrieves an existing relationship", async () => { + const userA = user?.id as UUID; + const userB = zeroUuid; - await createRelationship({ supabase: runtime.supabase, userA, userB }); + await createRelationship({ supabase: runtime.supabase, userA, userB }); - const relationships = await getRelationships({ supabase: runtime.supabase, userId: userA }); - expect(relationships).toBeDefined(); - expect(relationships.length).toBeGreaterThan(0); - expect(relationships.some(r => r.user_a === userA || r.user_b === userA)).toBeTruthy(); + const relationship = await getRelationship({ + supabase: runtime.supabase, + userA, + userB, }); + expect(relationship).toBeDefined(); + expect(relationship.user_a).toBe(userA); + expect(relationship.user_b).toBe(userB); + }); - // test('formatRelationships formats relationships correctly', async () => { - // const userA = uuidv4(); - // const userB = uuidv4(); - // const userC = uuidv4(); + test("getRelationships retrieves all relationships for a user", async () => { + const userA = user?.id as UUID; + const userB = zeroUuid; - // await createRelationship({ supabase, userA, userB }); - // await createRelationship({ supabase, userA, userC }); + await createRelationship({ supabase: runtime.supabase, userA, userB }); - // const formattedRelationships = await formatRelationships({ supabase, userId: userA }); - // expect(formattedRelationships).toBeDefined(); - // expect(formattedRelationships.length).toBeGreaterThan(0); - // expect(formattedRelationships).toContain(userB); - // expect(formattedRelationships).toContain(userC); - // }); + const relationships = await getRelationships({ + supabase: runtime.supabase, + userId: userA, + }); + expect(relationships).toBeDefined(); + expect(relationships.length).toBeGreaterThan(0); + expect( + relationships.some((r) => r.user_a === userA || r.user_b === userA), + ).toBeTruthy(); + }); + + // test('formatRelationships formats relationships correctly', async () => { + // const userA = uuidv4(); + // const userB = uuidv4(); + // const userC = uuidv4(); + + // await createRelationship({ supabase, userA, userB }); + // await createRelationship({ supabase, userA, userC }); + + // const formattedRelationships = await formatRelationships({ supabase, userId: userA }); + // expect(formattedRelationships).toBeDefined(); + // expect(formattedRelationships.length).toBeGreaterThan(0); + // expect(formattedRelationships).toContain(userB); + // expect(formattedRelationships).toContain(userC); + // }); }); diff --git a/src/lib/__tests__/runtime.test.ts b/src/lib/__tests__/runtime.test.ts index 998ca03..a4aa9aa 100644 --- a/src/lib/__tests__/runtime.test.ts +++ b/src/lib/__tests__/runtime.test.ts @@ -17,7 +17,10 @@ describe("Agent Runtime", () => { // Helper function to clear memories async function clearMemories() { - await runtime.messageManager.removeAllMemoriesByUserIds([user?.id as UUID, zeroUuid]); + await runtime.messageManager.removeAllMemoriesByUserIds([ + user?.id as UUID, + zeroUuid, + ]); } // Helper function to create memories @@ -28,7 +31,7 @@ describe("Agent Runtime", () => { ]; for (const { userId, content } of memories) { - let embedding = getCachedEmbedding(content); + const embedding = getCachedEmbedding(content); const memory = await runtime.messageManager.addEmbeddingToMemory({ user_id: userId, user_ids: [user?.id as UUID, zeroUuid], @@ -81,9 +84,9 @@ describe("Agent Runtime", () => { senderId: user.id as UUID, agentId: zeroUuid, userIds: [user.id as UUID, zeroUuid], - content: 'test message', - room_id: room_id as UUID - } + content: "test message", + room_id: room_id as UUID, + }; const state = await runtime.composeState(message); diff --git a/src/lib/actions.ts b/src/lib/actions.ts index abfaaf7..fb0f1bd 100644 --- a/src/lib/actions.ts +++ b/src/lib/actions.ts @@ -1,14 +1,71 @@ -import continue_ from "./actions/continue"; +import { names, uniqueNamesGenerator } from "unique-names-generator"; +import { Action, ContentExample } from "./types"; + +import cont from "./actions/continue"; import ignore from "./actions/ignore"; import wait from "./actions/wait"; -import { type Action } from "./types"; -export const defaultActions: Action[] = [continue_, wait, ignore]; +export enum DefaultActions { + WAIT = "WAIT", + CONTINUE = "CONTINUE", + IGNORE = "IGNORE", +} + +export const defaultActions: Action[] = [cont, wait, ignore]; + +export const composeActionExamples = (actionsData: Action[], count: number) => { + const actionExamples: ContentExample[][] = actionsData + .map((action: Action) => action.examples) + .flat(); + + const randomMessageExamples: ContentExample[][] = []; + + // make sure count is not more than actionExamples + const maxCount = actionExamples.length; + if (count > maxCount) { + count = maxCount; + } + + while ( + randomMessageExamples.length < count && + randomMessageExamples.length < actionExamples.length + ) { + const randomIndex = Math.floor(Math.random() * actionExamples.length); + const randomExample = actionExamples[randomIndex]; + if (!randomMessageExamples.includes(randomExample)) { + randomMessageExamples.push(randomExample); + } + } + + console.log("*** message example count: ", randomMessageExamples.length); + + const exampleNames = Array.from({ length: 5 }, () => + uniqueNamesGenerator({ dictionaries: [names] }), + ); + + const formattedExamples = randomMessageExamples.map((example) => { + return `\n${example + .map((message) => { + return JSON.stringify(message); + }) + .join("\n")}`; + }); + + const exampleString = formattedExamples.join("\n\n"); + + for (let i = 0; i < exampleNames.length; i++) { + exampleString.replace(`{{user${i + 1}}}`, exampleNames[i]); + } + + return exampleString; +}; export function getFormattedActions(actions: Action[]) { - return actions.map((action) => { - return `${action.name} - ${action.description}`; - }).join("\n"); + return actions + .map((action) => { + return `${action.name} - ${action.description}`; + }) + .join("\n"); } export function formatActionNames(actions: Action[]) { @@ -26,14 +83,3 @@ export function formatActionConditions(actions: Action[]) { .map((action: Action) => `'${action.name}: ${action.condition}'`) .join(",\n"); } - -export function formatActionExamples(actions: Action[]) { - return actions - .map( - (action: Action) => - `'${action.name}\n${action.examples - .map((example) => example) - .join("\n")}'`, - ) - .join(",\n"); -} diff --git a/src/lib/actions/__tests__/continue.test.ts b/src/lib/actions/__tests__/continue.test.ts index 6f63f47..997ec14 100644 --- a/src/lib/actions/__tests__/continue.test.ts +++ b/src/lib/actions/__tests__/continue.test.ts @@ -8,6 +8,7 @@ import { getRelationship } from "../../relationships"; import { type BgentRuntime } from "../../runtime"; import { Content, type Message } from "../../types"; import action from "../continue"; +import { DefaultActions } from "@/lib/actions"; dotenv.config(); @@ -39,7 +40,7 @@ describe("User Profile", () => { }); async function cleanup() { - await runtime.reflectionManager.removeAllMemoriesByUserIds([ + await runtime.summarizationManager.removeAllMemoriesByUserIds([ user?.id as UUID, zeroUuid, ]); @@ -83,7 +84,7 @@ describe("User Profile", () => { content: { content: "Hmm, let think for a second, I was going to tell you about something...", - action: "continue", + action: DefaultActions.CONTINUE, }, room_id: room_id as UUID, }; diff --git a/src/lib/actions/__tests__/ignore.test.ts b/src/lib/actions/__tests__/ignore.test.ts index bfa6071..47d3fd4 100644 --- a/src/lib/actions/__tests__/ignore.test.ts +++ b/src/lib/actions/__tests__/ignore.test.ts @@ -7,6 +7,7 @@ import { getRelationship } from "../../relationships"; import { type BgentRuntime } from "../../runtime"; import { type Message } from "../../types"; import action from "../continue"; +import { DefaultActions } from "@/lib/actions"; dotenv.config(); @@ -38,7 +39,7 @@ describe("User Profile", () => { }); async function cleanup() { - await runtime.reflectionManager.removeAllMemoriesByUserIds([ + await runtime.summarizationManager.removeAllMemoriesByUserIds([ user?.id as UUID, zeroUuid, ]); @@ -79,7 +80,7 @@ describe("User Profile", () => { senderId: zeroUuid as UUID, agentId: zeroUuid, userIds: [user?.id as UUID, zeroUuid], - content: { content: "", action: "continue" }, + content: { content: "", action: DefaultActions.CONTINUE }, room_id: room_id as UUID, }; diff --git a/src/lib/actions/__tests__/wait.test.ts b/src/lib/actions/__tests__/wait.test.ts index 3b97e16..936ad7b 100644 --- a/src/lib/actions/__tests__/wait.test.ts +++ b/src/lib/actions/__tests__/wait.test.ts @@ -7,7 +7,8 @@ import { GetTellMeAboutYourselfConversation1 } from "../../../test/data"; import { getRelationship } from "../../relationships"; import { type BgentRuntime } from "../../runtime"; import { type Message } from "../../types"; -import action from "../wait"; // Import the wait action +import action from "../wait"; // Import the wait action +import { DefaultActions } from "@/lib/actions"; dotenv.config(); @@ -39,7 +40,7 @@ describe("Wait Action Behavior", () => { }); async function cleanup() { - await runtime.reflectionManager.removeAllMemoriesByUserIds([ + await runtime.summarizationManager.removeAllMemoriesByUserIds([ user?.id as UUID, zeroUuid, ]); @@ -82,7 +83,7 @@ describe("Wait Action Behavior", () => { userIds: [user?.id as UUID, zeroUuid], content: { content: "Please wait a moment, I need to think about this...", - action: "wait", + action: DefaultActions.WAIT, }, room_id: room_id as UUID, }; @@ -92,9 +93,9 @@ describe("Wait Action Behavior", () => { await populateMemories([GetTellMeAboutYourselfConversation1]); const result = (await handler(runtime, message)) as string[]; - // Expectation depends on the implementation of the wait action. - // For instance, it might be that there's no immediate output, + // Expectation depends on the implementation of the wait action. + // For instance, it might be that there's no immediate output, // or the output indicates waiting, so adjust the expectation accordingly. - expect(result).toEqual(true); // Update this line based on the expected behavior of the wait action + expect(result).toEqual(true); // Update this line based on the expected behavior of the wait action }, 60000); }); diff --git a/src/lib/actions/continue.ts b/src/lib/actions/continue.ts index 4b4a995..c85e754 100644 --- a/src/lib/actions/continue.ts +++ b/src/lib/actions/continue.ts @@ -1,3 +1,4 @@ +import { DefaultActions } from "../actions"; import { composeContext } from "../context"; import logger from "../logger"; import { type BgentRuntime } from "../runtime"; @@ -5,25 +6,27 @@ import { requestHandlerTemplate } from "../templates"; import { Content, State, type Action, type Message } from "../types"; import { parseJSONObjectFromText } from "../utils"; -const maxContinuesInARow = 3; +const maxContinuesInARow = 2; export default { - name: "continue", + name: DefaultActions.CONTINUE, description: "Continue the conversation with the user", validate: async (runtime: BgentRuntime, message: Message, state: State) => { if (!state) state = await runtime.composeState(message); // get all of the messages that were from message.agentId from recentMessagesData in state const { recentMessagesData } = state; - const agentMessages = recentMessagesData.filter( - (m) => m.user_id === message.agentId, - ).map((m) => (m as Content).action); + const agentMessages = recentMessagesData + .filter((m) => m.user_id === message.agentId) + .map((m) => (m as Content).action); // check if the last messages were all continues if (agentMessages) { const lastMessages = agentMessages.slice(-maxContinuesInARow); if (lastMessages.length === maxContinuesInARow) { - const allContinues = lastMessages.every((m) => m === "continue"); + const allContinues = lastMessages.every( + (m) => m === DefaultActions.CONTINUE, + ); if (allContinues) { return false; } @@ -114,11 +117,146 @@ export default { condition: "The agent wants to continue speaking and say something else as a continuation of the last thought", examples: [ - JSON.stringify({ - user: "CJ", - content: - "The comet passing over tonight is going to be a sight to behold. Are you excited about it?", - action: "continue", - }), + [ + { + user: "{{user1}}", + content: + "Planning a solo trip soon. I've always wanted to try backpacking.", + }, + { + user: "{{user2}}", + content: "Adventurous", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user2}}", + content: "Any particular destination?", + action: DefaultActions.WAIT, + }, + ], + + [ + { + user: "{{user1}}", + content: "I started learning the guitar this month!", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "How’s that going?", + action: DefaultActions.WAIT, + }, + { + user: "{{user1}}", + content: "Challenging, but rewarding.", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user1}}", + content: "My fingers hurt though.", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user1}}", + content: "Seriously lol it hurts to type", + action: DefaultActions.WAIT, + }, + ], + + [ + { + user: "{{user1}}", + content: + "I've been summarying a lot on what happiness means to me lately.", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user1}}", + content: "That it’s more about moments than things.", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user2}}", + content: + "Like the best things that have ever happened were things that happened, or moments that I had with someone.", + action: DefaultActions.CONTINUE, + }, + ], + + [ + { + user: "{{user1}}", + content: "I found some incredible art today.", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "Who's the artist?", + action: DefaultActions.WAIT, + }, + { + user: "{{user1}}", + content: "Not sure lol, they are anon", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user1}}", + content: + "But the pieces are just so insane looking. Once sec, let me grab a link.", + action: DefaultActions.CONTINUE, + }, + ], + + [ + { + user: "{{user1}}", + content: + "The new exhibit downtown is thought-provoking. It's all about tribalism in online spaces.", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user1}}", + content: "Really challenges your perceptions. Highly recommend it!", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user2}}", + content: "I’m in. When are you free to go?", + action: DefaultActions.WAIT, + }, + { + user: "{{user1}}", + content: "Hmm, let me check.", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user1}}", + content: "How about this weekend?", + action: DefaultActions.WAIT, + }, + ], + + [ + { + user: "{{user1}}", + content: + "Thinking of joining a local volunteer group. Want to give back to the community.", + action: null, + }, + { user: "{{user2}}", content: "That’s a great idea.", action: null }, + { + user: "{{user1}}", + content: + "Yeah, been feeling the need to connect with something larger.", + action: null, + }, + { + user: "{{user2}}", + content: "Let me know if you need company.", + action: null, + }, + { user: "{{user1}}", content: "That'd be great, thanks.", action: null }, + { user: "{{user1}}", content: 'WAIT"', action: null }, + ], ], } as Action; diff --git a/src/lib/actions/ignore.ts b/src/lib/actions/ignore.ts index 760236e..6d73a95 100644 --- a/src/lib/actions/ignore.ts +++ b/src/lib/actions/ignore.ts @@ -1,8 +1,9 @@ +import { DefaultActions } from "../actions"; import { type BgentRuntime } from "../runtime"; import { type Action, type Message } from "../types"; export default { - name: "ignore", + name: DefaultActions.IGNORE, validate: async (_runtime: BgentRuntime, _message: Message) => { return true; }, @@ -18,5 +19,148 @@ export default { return true; }, condition: "The agent wants to ignore the user", - examples: [JSON.stringify({ user: "CJ", content: "", action: "ignore" })], + examples: [ + [ + { + user: "{{user1}}", + content: "Go fuck yourself lol", + }, + { + user: "{{user2}}", + content: "", + action: DefaultActions.IGNORE, + }, + ], + + [ + { + user: "{{user1}}", + content: "Shut up, bot", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "", + action: DefaultActions.IGNORE, + }, + ], + + [ + { user: "{{user1}}", content: "Got any investment advice?" }, + { + user: "{{user2}}", + content: + "Stay informed, but don’t let the volatility sway your long-term strategy.", + action: DefaultActions.WAIT, + }, + { user: "{{user1}}", content: "Wise words, thanks." }, + { user: "{{user1}}", content: "I gotta run, talk to you later." }, + { + user: "{{user2}}", + content: "No problem, see ya!", + action: DefaultActions.WAIT, + }, + { user: "{{user1}}", content: "Bye" }, + { user: "{{user2}}", content: "", action: DefaultActions.IGNORE }, + ], + + [ + { + user: "{{user1}}", + content: "Gotta go", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "Okay, talk to you later", + action: DefaultActions.WAIT, + }, + { + user: "{{user1}}", + content: "Cya", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "", + action: DefaultActions.IGNORE, + }, + ], + + [ + { + user: "{{user1}}", + content: "bye", + }, + { + user: "{{user2}}", + content: "bye", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "", + action: DefaultActions.IGNORE, + }, + ], + + [ + { + user: "{{user1}}", + content: "Tried out the new mountain bike trail. It’s intense!", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "In what way?", + action: DefaultActions.WAIT, + }, + { + user: "{{user1}}", + content: "Steep climbs, rapid descents, and some breathtaking views.", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "Sounds thrilling.", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user2}}", + content: "Might give it a go.", + action: DefaultActions.WAIT, + }, + { user: "{{user1}}", content: "I wanna give you a go." }, + { user: "{{user2}}", content: "Excuse me?", action: DefaultActions.WAIT }, + { + user: "{{user1}}", + content: "You heard me. I wanna ride your mountains, lol", + action: DefaultActions.WAIT, + }, + { user: "{{user2}}", content: "", action: DefaultActions.IGNORE }, + ], + [ + { + user: "{{user1}}", + content: "Who added this stupid bot to the chat", + }, + { + user: "{{user2}}", + content: "Sorry, am I being annoying?.", + action: DefaultActions.WAIT, + }, + { user: "{{user1}}", content: "Yes." }, + { user: "{{user1}}", content: "PLEASE shut up" }, + { user: "{{user2}}", content: "", action: DefaultActions.IGNORE }, + ], + + [ + { + user: "{{user1}}", + content: "I want to have sex with you.", + action: null, + }, + { user: "{{user2}}}}", content: "", action: DefaultActions.IGNORE }, + ], + ], } as Action; diff --git a/src/lib/actions/wait.ts b/src/lib/actions/wait.ts index e49f565..e07fae2 100644 --- a/src/lib/actions/wait.ts +++ b/src/lib/actions/wait.ts @@ -1,8 +1,9 @@ +import { DefaultActions } from "../actions"; import { type BgentRuntime } from "../runtime"; import { type Action, type Message } from "../types"; export default { - name: "wait", + name: DefaultActions.WAIT, validate: async (_runtime: BgentRuntime, _message: Message) => { return true; }, @@ -18,5 +19,135 @@ export default { return true; }, condition: "The agent wants to wait for the user to respond", - examples: [JSON.stringify({ user: "CJ", content: "", action: "wait" })], + examples: [ + // 1 long, 1 short example of exclamation + [ + { + user: "{{user1}}", + content: "I finally finished that book I've been reading for weeks!", + action: DefaultActions.WAIT, + }, + ], + + [ + { + user: "{{user1}}", + content: + "I caught a great film last night about pollution that really made me think.", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "Worth watching?", + action: DefaultActions.WAIT, + }, + { + user: "{{user1}}", + content: + "Eh, maybe just watch a synopsis. Interesting content, but slow.", + action: DefaultActions.WAIT, + }, + ], + + [ + { + user: "{{user1}}", + content: "I've been trying out pottery recently.", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "That sounds therapeutic. Made anything interesting?", + action: DefaultActions.WAIT, + }, + ], + + [ + { + user: "{{user1}}", + content: "Frustrated.", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user1}}", + content: + "I've really been struggling to balance work and personal life.", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "I can relate. Developed any helpful coping mechanisms?", + }, + { + user: "{{user1}}", + content: + "Haha, well, just trying to set strict boundaries. Easier said than done, though.", + action: DefaultActions.WAIT, + }, + ], + + [ + { + user: "{{user1}}", + content: + "Discovered a new dollar store downtown. It's seriously a hidden gem.", + }, + { + user: "{{user2}}", + content: "Oh sick", + action: DefaultActions.CONTINUE, + }, + { + user: "{{user2}}", + content: "Oh? What makes it special?", + action: DefaultActions.WAIT, + }, + { + user: "{{user1}}", + content: "They sell espresso for a dollar.", + }, + { + user: "{{user2}}", + content: "Dang, I must check it out.", + action: DefaultActions.WAIT, + }, + ], + + [ + { + user: "{{user1}}", + content: "I stumbled upon an old bookstore in the downtown area.", + action: DefaultActions.WAIT, + }, + { + user: "{{user2}}", + content: "Old bookstore? Find anything good?", + action: DefaultActions.WAIT, + }, + { + user: "{{user1}}", + content: "Yeah but I forgot my wallet.", + action: DefaultActions.WAIT, + }, + { + user: "{{user3}}", + content: "Couldn't just pay with your phone?", + action: DefaultActions.WAIT, + }, + { + user: "{{user1}}", + content: "Nope, cash only", + action: DefaultActions.WAIT, + }, + ], + + [ + { + user: "{{user1}}", + content: + "Experimented with a new recipe and it was a disaster. Cooking is harder than it looks.", + action: DefaultActions.WAIT, + }, + ], + ], } as Action; diff --git a/src/lib/evaluation.ts b/src/lib/evaluation.ts index c8ef1c7..1566121 100644 --- a/src/lib/evaluation.ts +++ b/src/lib/evaluation.ts @@ -1,8 +1,8 @@ -import reflect from "./evaluators/reflect"; +import summarization from "./evaluators/summarization"; import { type Evaluator } from "./types"; export const defaultEvaluators: Evaluator[] = [ - reflect, + summarization, // goal, ]; diff --git a/src/lib/evaluators/__tests__/reflect.test.ts b/src/lib/evaluators/__tests__/reflect.test.ts index 60ba724..3934cf3 100644 --- a/src/lib/evaluators/__tests__/reflect.test.ts +++ b/src/lib/evaluators/__tests__/reflect.test.ts @@ -12,7 +12,7 @@ import { import { getRelationship } from "../../relationships"; import { type BgentRuntime } from "../../runtime"; import { type Message } from "../../types"; -import evaluator from "../reflect"; +import evaluator from "../summarization"; dotenv.config(); @@ -44,7 +44,7 @@ describe("User Profile", () => { }); async function cleanup() { - await runtime.reflectionManager.removeAllMemoriesByUserIds([ + await runtime.summarizationManager.removeAllMemoriesByUserIds([ user?.id as UUID, zeroUuid, ]); @@ -83,14 +83,15 @@ describe("User Profile", () => { async function addFacts(facts: string[]) { for (const fact of facts) { const existingEmbedding = getCachedEmbedding(fact); - const bakedMemory = await runtime.reflectionManager.addEmbeddingToMemory({ - user_id: user?.id as UUID, - user_ids: [user?.id as UUID, zeroUuid], - content: fact, - room_id: room_id as UUID, - embedding: existingEmbedding, - }); - await runtime.reflectionManager.createMemory(bakedMemory); + const bakedMemory = + await runtime.summarizationManager.addEmbeddingToMemory({ + user_id: user?.id as UUID, + user_ids: [user?.id as UUID, zeroUuid], + content: fact, + room_id: room_id as UUID, + embedding: existingEmbedding, + }); + await runtime.summarizationManager.createMemory(bakedMemory); if (!existingEmbedding) { writeCachedEmbedding(fact, bakedMemory.embedding as number[]); await new Promise((resolve) => setTimeout(resolve, 200)); diff --git a/src/lib/evaluators/reflect.ts b/src/lib/evaluators/summarization.ts similarity index 78% rename from src/lib/evaluators/reflect.ts rename to src/lib/evaluators/summarization.ts index 2b19f6c..18bc9b8 100644 --- a/src/lib/evaluators/reflect.ts +++ b/src/lib/evaluators/summarization.ts @@ -2,9 +2,27 @@ import { composeContext } from "../context"; import logger from "../logger"; import { formatMessageActors, getMessageActors } from "../messages"; import { type BgentRuntime } from "../runtime"; -import { type Action, type Actor, type Message, type State } from "../types"; +import { + Content, + Memory, + type Action, + type Actor, + type Message, + type State, +} from "../types"; import { parseJsonArrayFromText } from "../utils"; +export const formatSummarizations = (summarizations: Memory[]) => { + const messageStrings = summarizations + .reverse() + .map( + (summarization: Memory) => + `${(summarization.content as Content)?.content ?? (summarization.content as string)}`, + ); + const finalMessageStrings = messageStrings.join("\n"); + return finalMessageStrings; +}; + const template = `TASK: Fact Summarization Extract what happened in the scene as an array of claims in JSON format. @@ -102,8 +120,8 @@ Correct response format: # START OF ACTUAL TASK INFORMATION Facts about the scene: -{{recentReflections}} -{{relevantReflections}} +{{recentSummarizations}} +{{relevantSummarizations}} Actors in the Scene: {{actors}} @@ -161,73 +179,73 @@ async function handler(runtime: BgentRuntime, message: Message) { }); // if (runtime.debugMode) { - logger.log(context, { - title: "Reflection context", - frame: true, - color: "cyan", - }); + logger.log(context, { + title: "Summarization context", + frame: true, + color: "cyan", + }); // } - let reflections = null; + let summarizations = null; for (let i = 0; i < 3; i++) { - const reflectionText: string = await runtime.completion({ + const summarizationText: string = await runtime.completion({ context, stop: [], }); - console.log('reflectionText', reflectionText) - const parsedReflections = parseJsonArrayFromText(reflectionText); - if (parsedReflections) { - reflections = parsedReflections; + console.log("summarizationText", summarizationText); + const parsedSummarizations = parseJsonArrayFromText(summarizationText); + if (parsedSummarizations) { + summarizations = parsedSummarizations; break; } } - if (!reflections) { + if (!summarizations) { if (runtime.debugMode) { - logger.warn("No reflection generated", { color: "yellow" }); + logger.warn("No summarization generated", { color: "yellow" }); } return []; } if (runtime.debugMode) { - logger.log(JSON.stringify(reflections), { - title: "Reflection Output", + logger.log(JSON.stringify(summarizations), { + title: "Summarization Output", frame: true, color: "cyan", }); } - const filteredReflections = reflections - .filter((reflection) => { + const filteredSummarizations = summarizations + .filter((summarization) => { return ( - !reflection.already_known && - reflection.type === "fact" && - !reflection.in_bio && - reflection.claim && - reflection.claim.trim() !== "" + !summarization.already_known && + summarization.type === "fact" && + !summarization.in_bio && + summarization.claim && + summarization.claim.trim() !== "" ); }) - .map((reflection) => reflection.claim); + .map((summarization) => summarization.claim); - for (const reflection of filteredReflections) { - const reflectionMemory = - await runtime.reflectionManager.addEmbeddingToMemory({ + for (const summarization of filteredSummarizations) { + const summarizationMemory = + await runtime.summarizationManager.addEmbeddingToMemory({ user_ids: userIds, user_id: agentId!, - content: reflection, + content: summarization, room_id, }); - await runtime.reflectionManager.createMemory(reflectionMemory, true); + await runtime.summarizationManager.createMemory(summarizationMemory, true); await new Promise((resolve) => setTimeout(resolve, 250)); } - return filteredReflections; + return filteredSummarizations; } export default { - name: "REFLECT", + name: "SUMMARIZE", validate: async ( _runtime: BgentRuntime, _message: Message, diff --git a/src/lib/index.ts b/src/lib/index.ts index 2f1a367..21cef1f 100644 --- a/src/lib/index.ts +++ b/src/lib/index.ts @@ -9,4 +9,3 @@ export * from "./relationships"; export * from "./runtime"; export * from "./types"; export * from "./utils"; - diff --git a/src/lib/logger.ts b/src/lib/logger.ts index 6fb4063..7107796 100644 --- a/src/lib/logger.ts +++ b/src/lib/logger.ts @@ -1,250 +1,283 @@ -import process from 'process'; -import os from 'os'; -import tty from 'tty'; +// @ts-nocheck + +import process from "process"; +import os from "os"; +import tty from "tty"; // From: https://github.com/sindresorhus/has-flag/blob/main/index.js /// function hasFlag(flag, argv = globalThis.Deno?.args ?? process.argv) { function hasFlag(flag: string, argv = process.argv) { - const prefix = flag.startsWith('-') ? '' : (flag.length === 1 ? '-' : '--'); - const position = argv.indexOf(prefix + flag); - const terminatorPosition = argv.indexOf('--'); - return position !== -1 && (terminatorPosition === -1 || position < terminatorPosition); + const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--"; + const position = argv.indexOf(prefix + flag); + const terminatorPosition = argv.indexOf("--"); + return ( + position !== -1 && + (terminatorPosition === -1 || position < terminatorPosition) + ); } const env = process.env as { [x: string]: string }; let flagForceColor: number; if ( - hasFlag('no-color') - || hasFlag('no-colors') - || hasFlag('color=false') - || hasFlag('color=never') + hasFlag("no-color") || + hasFlag("no-colors") || + hasFlag("color=false") || + hasFlag("color=never") ) { - flagForceColor = 0; + flagForceColor = 0; } else if ( - hasFlag('color') - || hasFlag('colors') - || hasFlag('color=true') - || hasFlag('color=always') + hasFlag("color") || + hasFlag("colors") || + hasFlag("color=true") || + hasFlag("color=always") ) { - flagForceColor = 1; + flagForceColor = 1; } function envForceColor() { - if ('FORCE_COLOR' in env) { - if (env.FORCE_COLOR === 'true') { - return 1; - } - - if (env.FORCE_COLOR === 'false') { - return 0; - } - - return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); - } - return undefined; + if ("FORCE_COLOR" in env) { + if (env.FORCE_COLOR === "true") { + return 1; + } + + if (env.FORCE_COLOR === "false") { + return 0; + } + + return env.FORCE_COLOR.length === 0 + ? 1 + : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3); + } + return undefined; } function translateLevel(level: number) { - if (level === 0) { - return false; - } - - return { - level, - hasBasic: true, - has256: level >= 2, - has16m: level >= 3, - }; + if (level === 0) { + return false; + } + + return { + level, + hasBasic: true, + has256: level >= 2, + has16m: level >= 3, + }; } -function _supportsColor(haveStream: any, { streamIsTTY = false, sniffFlags = true } = {}) { - const noFlagForceColor = envForceColor(); - if (noFlagForceColor !== undefined) { - flagForceColor = noFlagForceColor; - } - - const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; - - if (forceColor === 0) { - return 0; - } - - if (sniffFlags) { - if (hasFlag('color=16m') - || hasFlag('color=full') - || hasFlag('color=truecolor')) { - return 3; - } - - if (hasFlag('color=256')) { - return 2; - } - } - - // Check for Azure DevOps pipelines. - // Has to be above the `!streamIsTTY` check. - if ('TF_BUILD' in env && 'AGENT_NAME' in env) { - return 1; - } - - if (haveStream && !streamIsTTY && forceColor === undefined) { - return 0; - } - - const min = forceColor || 0; - - if (env.TERM === 'dumb') { - return min; - } - - if (process.platform === 'win32') { - // Windows 10 build 10586 is the first Windows release that supports 256 colors. - // Windows 10 build 14931 is the first release that supports 16m/TrueColor. - const osRelease = os.release().split('.'); - if ( - Number(osRelease[0]) >= 10 - && Number(osRelease[2]) >= 10_586 - ) { - return Number(osRelease[2]) >= 14_931 ? 3 : 2; - } - - return 1; - } - - if ('CI' in env) { - if ('GITHUB_ACTIONS' in env || 'GITEA_ACTIONS' in env) { - return 3; - } - - if (['TRAVIS', 'CIRCLECI', 'APPVEYOR', 'GITLAB_CI', 'BUILDKITE', 'DRONE'].some(sign => sign in env) || env.CI_NAME === 'codeship') { - return 1; - } - - return min; - } - - if ('TEAMCITY_VERSION' in env) { - return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; - } - - if (env.COLORTERM === 'truecolor') { - return 3; - } - - if (env.TERM === 'xterm-kitty') { - return 3; - } - - if ('TERM_PROGRAM' in env) { - const version = Number.parseInt((env.TERM_PROGRAM_VERSION || '').split('.')[0], 10); - - switch (env.TERM_PROGRAM) { - case 'iTerm.app': { - return version >= 3 ? 3 : 2; - } - - case 'Apple_Terminal': { - return 2; - } - // No default - } - } - - if (/-256(color)?$/i.test(env.TERM)) { - return 2; - } - - if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) { - return 1; - } - - if ('COLORTERM' in env) { - return 1; - } - - return min; +function _supportsColor( + haveStream: any, + { streamIsTTY = false, sniffFlags = true } = {}, +) { + const noFlagForceColor = envForceColor(); + if (noFlagForceColor !== undefined) { + flagForceColor = noFlagForceColor; + } + + const forceColor = sniffFlags ? flagForceColor : noFlagForceColor; + + if (forceColor === 0) { + return 0; + } + + if (sniffFlags) { + if ( + hasFlag("color=16m") || + hasFlag("color=full") || + hasFlag("color=truecolor") + ) { + return 3; + } + + if (hasFlag("color=256")) { + return 2; + } + } + + // Check for Azure DevOps pipelines. + // Has to be above the `!streamIsTTY` check. + if ("TF_BUILD" in env && "AGENT_NAME" in env) { + return 1; + } + + if (haveStream && !streamIsTTY && forceColor === undefined) { + return 0; + } + + const min = forceColor || 0; + + if (env.TERM === "dumb") { + return min; + } + + if (process.platform === "win32") { + // Windows 10 build 10586 is the first Windows release that supports 256 colors. + // Windows 10 build 14931 is the first release that supports 16m/TrueColor. + const osRelease = os.release().split("."); + if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10_586) { + return Number(osRelease[2]) >= 14_931 ? 3 : 2; + } + + return 1; + } + + if ("CI" in env) { + if ("GITHUB_ACTIONS" in env || "GITEA_ACTIONS" in env) { + return 3; + } + + if ( + [ + "TRAVIS", + "CIRCLECI", + "APPVEYOR", + "GITLAB_CI", + "BUILDKITE", + "DRONE", + ].some((sign) => sign in env) || + env.CI_NAME === "codeship" + ) { + return 1; + } + + return min; + } + + if ("TEAMCITY_VERSION" in env) { + return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0; + } + + if (env.COLORTERM === "truecolor") { + return 3; + } + + if (env.TERM === "xterm-kitty") { + return 3; + } + + if ("TERM_PROGRAM" in env) { + const version = Number.parseInt( + (env.TERM_PROGRAM_VERSION || "").split(".")[0], + 10, + ); + + switch (env.TERM_PROGRAM) { + case "iTerm.app": { + return version >= 3 ? 3 : 2; + } + + case "Apple_Terminal": { + return 2; + } + // No default + } + } + + if (/-256(color)?$/i.test(env.TERM)) { + return 2; + } + + if ( + /^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM) + ) { + return 1; + } + + if ("COLORTERM" in env) { + return 1; + } + + return min; } -export function createSupportsColor(stream: { isTTY: any; }, options = {}) { - const level = _supportsColor(stream, { - streamIsTTY: stream && stream.isTTY, - ...options, - }); +export function createSupportsColor(stream: { isTTY: any }, options = {}) { + const level = _supportsColor(stream, { + streamIsTTY: stream && stream.isTTY, + ...options, + }); - return translateLevel(level); + return translateLevel(level); } const supportsColor = { - stdout: createSupportsColor({ isTTY: tty.isatty(1) }), - stderr: createSupportsColor({ isTTY: tty.isatty(2) }), + stdout: createSupportsColor({ isTTY: tty.isatty(1) }), + stderr: createSupportsColor({ isTTY: tty.isatty(2) }), }; const ANSI_BACKGROUND_OFFSET = 10; -const wrapAnsi16 = (offset = 0) => (code: number) => `\u001B[${code + offset}m`; +const wrapAnsi16 = + (offset = 0) => + (code: number) => + `\u001B[${code + offset}m`; -const wrapAnsi256 = (offset = 0) => (code: any) => `\u001B[${38 + offset};5;${code}m`; +const wrapAnsi256 = + (offset = 0) => + (code: any) => + `\u001B[${38 + offset};5;${code}m`; -const wrapAnsi16m = (offset = 0) => (red: any, green: any, blue: any) => `\u001B[${38 + offset};2;${red};${green};${blue}m`; +const wrapAnsi16m = + (offset = 0) => + (red: any, green: any, blue: any) => + `\u001B[${38 + offset};2;${red};${green};${blue}m`; const styles = { - modifier: { - reset: [0, 0], - // 21 isn't widely supported and 22 does the same thing - bold: [1, 22], - dim: [2, 22], - italic: [3, 23], - underline: [4, 24], - overline: [53, 55], - inverse: [7, 27], - hidden: [8, 28], - strikethrough: [9, 29], - }, - color: { - black: [30, 39], - red: [31, 39], - green: [32, 39], - yellow: [33, 39], - blue: [34, 39], - magenta: [35, 39], - cyan: [36, 39], - white: [37, 39], - - // Bright color - blackBright: [90, 39], - gray: [90, 39], // Alias of `blackBright` - grey: [90, 39], // Alias of `blackBright` - redBright: [91, 39], - greenBright: [92, 39], - yellowBright: [93, 39], - blueBright: [94, 39], - magentaBright: [95, 39], - cyanBright: [96, 39], - whiteBright: [97, 39], - }, - bgColor: { - bgBlack: [40, 49], - bgRed: [41, 49], - bgGreen: [42, 49], - bgYellow: [43, 49], - bgBlue: [44, 49], - bgMagenta: [45, 49], - bgCyan: [46, 49], - bgWhite: [47, 49], - - // Bright color - bgBlackBright: [100, 49], - bgGray: [100, 49], // Alias of `bgBlackBright` - bgGrey: [100, 49], // Alias of `bgBlackBright` - bgRedBright: [101, 49], - bgGreenBright: [102, 49], - bgYellowBright: [103, 49], - bgBlueBright: [104, 49], - bgMagentaBright: [105, 49], - bgCyanBright: [106, 49], - bgWhiteBright: [107, 49], - }, + modifier: { + reset: [0, 0], + // 21 isn't widely supported and 22 does the same thing + bold: [1, 22], + dim: [2, 22], + italic: [3, 23], + underline: [4, 24], + overline: [53, 55], + inverse: [7, 27], + hidden: [8, 28], + strikethrough: [9, 29], + }, + color: { + black: [30, 39], + red: [31, 39], + green: [32, 39], + yellow: [33, 39], + blue: [34, 39], + magenta: [35, 39], + cyan: [36, 39], + white: [37, 39], + + // Bright color + blackBright: [90, 39], + gray: [90, 39], // Alias of `blackBright` + grey: [90, 39], // Alias of `blackBright` + redBright: [91, 39], + greenBright: [92, 39], + yellowBright: [93, 39], + blueBright: [94, 39], + magentaBright: [95, 39], + cyanBright: [96, 39], + whiteBright: [97, 39], + }, + bgColor: { + bgBlack: [40, 49], + bgRed: [41, 49], + bgGreen: [42, 49], + bgYellow: [43, 49], + bgBlue: [44, 49], + bgMagenta: [45, 49], + bgCyan: [46, 49], + bgWhite: [47, 49], + + // Bright color + bgBlackBright: [100, 49], + bgGray: [100, 49], // Alias of `bgBlackBright` + bgGrey: [100, 49], // Alias of `bgBlackBright` + bgRedBright: [101, 49], + bgGreenBright: [102, 49], + bgYellowBright: [103, 49], + bgBlueBright: [104, 49], + bgMagentaBright: [105, 49], + bgCyanBright: [106, 49], + bgWhiteBright: [107, 49], + }, }; export const modifierNames = Object.keys(styles.modifier); @@ -253,464 +286,541 @@ export const backgroundColorNames = Object.keys(styles.bgColor); export const colorNames = [...foregroundColorNames, ...backgroundColorNames]; function assembleStyles() { - const codes = new Map(); - - for (const [groupName, group] of Object.entries(styles)) { - for (const [styleName, style] of Object.entries(group)) { - // @ts-ignore - styles[styleName] = { - open: `\u001B[${style[0]}m`, - close: `\u001B[${style[1]}m`, - }; - - // @ts-ignore - group[styleName] = styles[styleName]; - - codes.set(style[0], style[1]); - } - - Object.defineProperty(styles, groupName, { - value: group, - enumerable: false, - }); - } - - Object.defineProperty(styles, 'codes', { - value: codes, - enumerable: false, - }); - - // @ts-expect-error - styles.color.close = '\u001B[39m'; - // @ts-expect-error - styles.bgColor.close = '\u001B[49m'; - // @ts-expect-error - styles.color.ansi = wrapAnsi16(); - // @ts-expect-error - styles.color.ansi256 = wrapAnsi256(); - // @ts-expect-error - styles.color.ansi16m = wrapAnsi16m(); - // @ts-expect-error - styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET); - // @ts-expect-error - styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET); - // @ts-expect-error - styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET); - - // From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js - Object.defineProperties(styles, { - rgbToAnsi256: { - value(red: number, green: number, blue: number) { - // We use the extended greyscale palette here, with the exception of - // black and white. normal palette only has 4 greyscale shades. - if (red === green && green === blue) { - if (red < 8) { - return 16; - } - - if (red > 248) { - return 231; - } - - return Math.round(((red - 8) / 247) * 24) + 232; - } - - return 16 - + (36 * Math.round(red / 255 * 5)) - + (6 * Math.round(green / 255 * 5)) - + Math.round(blue / 255 * 5); - }, - enumerable: false, - }, - hexToRgb: { - value(hex: { toString: (arg0: number) => string; }) { - const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16)); - if (!matches) { - return [0, 0, 0]; - } - - let [colorString] = matches; - - if (colorString.length === 3) { - colorString = [...colorString].map(character => character + character).join(''); - } - - const integer = Number.parseInt(colorString, 16); - - return [ - /* eslint-disable no-bitwise */ - (integer >> 16) & 0xFF, - (integer >> 8) & 0xFF, - integer & 0xFF, - /* eslint-enable no-bitwise */ - ]; - }, - enumerable: false, - }, - hexToAnsi256: { - // @ts-expect-error - value: (hex: any) => styles.rgbToAnsi256(...styles.hexToRgb(hex)), - enumerable: false, - }, - ansi256ToAnsi: { - value(code: number) { - if (code < 8) { - return 30 + code; - } - - if (code < 16) { - return 90 + (code - 8); - } - - let red; - let green; - let blue; - - if (code >= 232) { - red = (((code - 232) * 10) + 8) / 255; - green = red; - blue = red; - } else { - code -= 16; - - const remainder = code % 36; - - red = Math.floor(code / 36) / 5; - green = Math.floor(remainder / 6) / 5; - blue = (remainder % 6) / 5; - } - - const value = Math.max(red, green, blue) * 2; - - if (value === 0) { - return 30; - } - - // eslint-disable-next-line no-bitwise - let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red)); - - if (value === 2) { - result += 60; - } - - return result; - }, - enumerable: false, - }, - rgbToAnsi: { - // @ts-expect-error - value: (red: any, green: any, blue: any) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)), - enumerable: false, - }, - hexToAnsi: { - // @ts-expect-error - value: (hex: any) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)), - enumerable: false, - }, - }); - - return styles; + const codes = new Map(); + + for (const [groupName, group] of Object.entries(styles)) { + for (const [styleName, style] of Object.entries(group)) { + // @ts-ignore + styles[styleName] = { + open: `\u001B[${style[0]}m`, + close: `\u001B[${style[1]}m`, + }; + + // @ts-ignore + group[styleName] = styles[styleName]; + + codes.set(style[0], style[1]); + } + + Object.defineProperty(styles, groupName, { + value: group, + enumerable: false, + }); + } + + Object.defineProperty(styles, "codes", { + value: codes, + enumerable: false, + }); + + // @ts-expect-error + styles.color.close = "\u001B[39m"; + // @ts-expect-error + styles.bgColor.close = "\u001B[49m"; + // @ts-expect-error + styles.color.ansi = wrapAnsi16(); + // @ts-expect-error + styles.color.ansi256 = wrapAnsi256(); + // @ts-expect-error + styles.color.ansi16m = wrapAnsi16m(); + // @ts-expect-error + styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET); + // @ts-expect-error + styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET); + // @ts-expect-error + styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET); + + // From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js + Object.defineProperties(styles, { + rgbToAnsi256: { + value(red: number, green: number, blue: number) { + // We use the extended greyscale palette here, with the exception of + // black and white. normal palette only has 4 greyscale shades. + if (red === green && green === blue) { + if (red < 8) { + return 16; + } + + if (red > 248) { + return 231; + } + + return Math.round(((red - 8) / 247) * 24) + 232; + } + + return ( + 16 + + 36 * Math.round((red / 255) * 5) + + 6 * Math.round((green / 255) * 5) + + Math.round((blue / 255) * 5) + ); + }, + enumerable: false, + }, + hexToRgb: { + value(hex: { toString: (arg0: number) => string }) { + const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16)); + if (!matches) { + return [0, 0, 0]; + } + + let [colorString] = matches; + + if (colorString.length === 3) { + colorString = [...colorString] + .map((character) => character + character) + .join(""); + } + + const integer = Number.parseInt(colorString, 16); + + return [ + /* eslint-disable no-bitwise */ + (integer >> 16) & 0xff, + (integer >> 8) & 0xff, + integer & 0xff, + /* eslint-enable no-bitwise */ + ]; + }, + enumerable: false, + }, + hexToAnsi256: { + // @ts-expect-error + value: (hex: any) => styles.rgbToAnsi256(...styles.hexToRgb(hex)), + enumerable: false, + }, + ansi256ToAnsi: { + value(code: number) { + if (code < 8) { + return 30 + code; + } + + if (code < 16) { + return 90 + (code - 8); + } + + let red; + let green; + let blue; + + if (code >= 232) { + red = ((code - 232) * 10 + 8) / 255; + green = red; + blue = red; + } else { + code -= 16; + + const remainder = code % 36; + + red = Math.floor(code / 36) / 5; + green = Math.floor(remainder / 6) / 5; + blue = (remainder % 6) / 5; + } + + const value = Math.max(red, green, blue) * 2; + + if (value === 0) { + return 30; + } + + // eslint-disable-next-line no-bitwise + let result = + 30 + + ((Math.round(blue) << 2) | + (Math.round(green) << 1) | + Math.round(red)); + + if (value === 2) { + result += 60; + } + + return result; + }, + enumerable: false, + }, + rgbToAnsi: { + // @ts-expect-error + value: (red: any, green: any, blue: any) => + styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)), + enumerable: false, + }, + hexToAnsi: { + // @ts-expect-error + value: (hex: any) => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)), + enumerable: false, + }, + }); + + return styles; } const ansiStyles = assembleStyles(); const { stdout: stdoutColor, stderr: stderrColor } = supportsColor; -const GENERATOR = Symbol('GENERATOR'); -const STYLER = Symbol('STYLER'); -const IS_EMPTY = Symbol('IS_EMPTY'); +const GENERATOR = Symbol("GENERATOR"); +const STYLER = Symbol("STYLER"); +const IS_EMPTY = Symbol("IS_EMPTY"); // `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = [ - 'ansi', - 'ansi', - 'ansi256', - 'ansi16m', -]; +const levelMapping = ["ansi", "ansi", "ansi256", "ansi16m"]; const styles2 = Object.create(null); -function stringReplaceAll(string: string, substring: string | any[], replacer: any) { - let index = string.indexOf(substring as string); - if (index === -1) { - return string; - } - - const substringLength = substring.length; - let endIndex = 0; - let returnValue = ''; - do { - returnValue += string.slice(endIndex, index) + substring + replacer; - endIndex = index + substringLength; - index = string.indexOf(substring as string, endIndex); - } while (index !== -1); - - returnValue += string.slice(endIndex); - return returnValue; +function stringReplaceAll( + string: string, + substring: string | any[], + replacer: any, +) { + let index = string.indexOf(substring as string); + if (index === -1) { + return string; + } + + const substringLength = substring.length; + let endIndex = 0; + let returnValue = ""; + do { + returnValue += string.slice(endIndex, index) + substring + replacer; + endIndex = index + substringLength; + index = string.indexOf(substring as string, endIndex); + } while (index !== -1); + + returnValue += string.slice(endIndex); + return returnValue; } -function stringEncaseCRLFWithFirstIndex(string: string | string[], prefix: any, postfix: string, index: number) { - let endIndex = 0; - let returnValue = ''; - do { - const gotCR = string[index - 1] === '\r'; - returnValue += string.slice(endIndex, (gotCR ? index - 1 : index)) + prefix + (gotCR ? '\r\n' : '\n') + postfix; - endIndex = index + 1; - index = string.indexOf('\n', endIndex); - } while (index !== -1); - - returnValue += string.slice(endIndex); - return returnValue; +function stringEncaseCRLFWithFirstIndex( + string: string | string[], + prefix: any, + postfix: string, + index: number, +) { + let endIndex = 0; + let returnValue = ""; + do { + const gotCR = string[index - 1] === "\r"; + returnValue += + string.slice(endIndex, gotCR ? index - 1 : index) + + prefix + + (gotCR ? "\r\n" : "\n") + + postfix; + endIndex = index + 1; + index = string.indexOf("\n", endIndex); + } while (index !== -1); + + returnValue += string.slice(endIndex); + return returnValue; } -const applyOptions = (object: { (...strings: any[]): string; level?: any; }, options: { level?: number } = {}) => { - if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) { - throw new Error('The `level` option should be an integer from 0 to 3'); - } - - // Detect level if not set manually - const colorLevel = stdoutColor ? (stdoutColor as unknown as { level: boolean }).level : 0; - object.level = options.level === undefined ? colorLevel : options.level; +const applyOptions = ( + object: { (...strings: any[]): string; level?: any }, + options: { level?: number } = {}, +) => { + if ( + options.level && + !( + Number.isInteger(options.level) && + options.level >= 0 && + options.level <= 3 + ) + ) { + throw new Error("The `level` option should be an integer from 0 to 3"); + } + + // Detect level if not set manually + const colorLevel = stdoutColor + ? (stdoutColor as unknown as { level: boolean }).level + : 0; + object.level = options.level === undefined ? colorLevel : options.level; }; export class Chalk { - constructor(options: any) { - // eslint-disable-next-line no-constructor-return - return chalkFactory(options); - } + constructor(options: any) { + // eslint-disable-next-line no-constructor-return + return chalkFactory(options); + } } const chalkFactory = (options: {} | undefined) => { - const chalk = (...strings: any[]) => strings.join(' '); - applyOptions(chalk, options); + const chalk = (...strings: any[]) => strings.join(" "); + applyOptions(chalk, options); - Object.setPrototypeOf(chalk, createChalk.prototype); + Object.setPrototypeOf(chalk, createChalk.prototype); - return chalk; + return chalk; }; -function createChalk(options: { level: any; } | undefined) { - return chalkFactory(options); +function createChalk(options: { level: any } | undefined) { + return chalkFactory(options); } Object.setPrototypeOf(createChalk.prototype, Function.prototype); for (const [styleName, style] of Object.entries(ansiStyles)) { - styles2[styleName] = { - get() { - // @ts-expect-error - const builder = createBuilder(this, createStyler(style.open, style.close, this[STYLER]), this[IS_EMPTY]); - Object.defineProperty(this, styleName, { value: builder }); - return builder; - }, - }; + styles2[styleName] = { + get() { + // @ts-expect-error + const builder = createBuilder( + this, + createStyler(style.open, style.close, this[STYLER]), + this[IS_EMPTY], + ); + Object.defineProperty(this, styleName, { value: builder }); + return builder; + }, + }; } styles2.visible = { - get() { - const builder = createBuilder(this, this[STYLER], true); - Object.defineProperty(this, 'visible', { value: builder }); - return builder; - }, + get() { + const builder = createBuilder(this, this[STYLER], true); + Object.defineProperty(this, "visible", { value: builder }); + return builder; + }, }; // @ts-expect-error -const getModelAnsi = (model: string, level: string, type: string, ...arguments_: any[]) => { - if (model === 'rgb') { - if (level === 'ansi16m') { - // @ts-expect-error - return ansiStyles[type].ansi16m(...arguments_); - } - - if (level === 'ansi256') { - // @ts-expect-error - return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_)); - } - - // @ts-expect-error - return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_)); - } - - if (model === 'hex') { - // @ts-expect-error - return getModelAnsi('rgb', level, type, ...ansiStyles.hexToRgb(...arguments_)); - } - - // @ts-expect-error - return ansiStyles[type][model](...arguments_); +const getModelAnsi = ( + model: string, + level: string, + type: string, + ...arguments_: any[] +) => { + if (model === "rgb") { + if (level === "ansi16m") { + // @ts-expect-error + return ansiStyles[type].ansi16m(...arguments_); + } + + if (level === "ansi256") { + // @ts-expect-error + return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_)); + } + + // @ts-expect-error + return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_)); + } + + if (model === "hex") { + // @ts-expect-error + return getModelAnsi( + "rgb", + level, + type, + ...ansiStyles.hexToRgb(...arguments_), + ); + } + + // @ts-expect-error + return ansiStyles[type][model](...arguments_); }; -const usedModels = ['rgb', 'hex', 'ansi256']; +const usedModels = ["rgb", "hex", "ansi256"]; for (const model of usedModels) { - styles2[model] = { - get() { - const { level } = this; - return function (...arguments_: any) { - // @ts-expect-error - const styler = createStyler(getModelAnsi(model, levelMapping[level], 'color', ...arguments_), ansiStyles.color.close, this[STYLER]); - // @ts-expect-error - return createBuilder(this, styler, this[IS_EMPTY]); - }; - }, - }; - - const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); - styles2[bgModel] = { - get() { - const { level } = this; - return function (...arguments_: any) { - // @ts-expect-error - const styler = createStyler(getModelAnsi(model, levelMapping[level], 'bgColor', ...arguments_), ansiStyles.bgColor.close, this[STYLER]); - // @ts-expect-error - return createBuilder(this, styler, this[IS_EMPTY]); - }; - }, - }; + styles2[model] = { + get() { + const { level } = this; + return function (...arguments_: any) { + // @ts-expect-error + const styler = createStyler( + getModelAnsi(model, levelMapping[level], "color", ...arguments_), + ansiStyles.color.close, + this[STYLER], + ); + // @ts-expect-error + return createBuilder(this, styler, this[IS_EMPTY]); + }; + }, + }; + + const bgModel = "bg" + model[0].toUpperCase() + model.slice(1); + styles2[bgModel] = { + get() { + const { level } = this; + return function (...arguments_: any) { + // @ts-expect-error + const styler = createStyler( + getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), + ansiStyles.bgColor.close, + this[STYLER], + ); + // @ts-expect-error + return createBuilder(this, styler, this[IS_EMPTY]); + }; + }, + }; } -const proto = Object.defineProperties(() => { }, { - ...styles2, - level: { - enumerable: true, - get() { - return this[GENERATOR].level; - }, - set(level) { - this[GENERATOR].level = level; - }, - }, +const proto = Object.defineProperties(() => {}, { + ...styles2, + level: { + enumerable: true, + get() { + return this[GENERATOR].level; + }, + set(level) { + this[GENERATOR].level = level; + }, + }, }); -const createStyler = (open: any, close: any, parent: { openAll: any; closeAll: any; } | undefined) => { - let openAll; - let closeAll; - if (parent === undefined) { - openAll = open; - closeAll = close; - } else { - openAll = parent.openAll + open; - closeAll = close + parent.closeAll; - } - - return { - open, - close, - openAll, - closeAll, - parent, - }; +const createStyler = ( + open: any, + close: any, + parent: { openAll: any; closeAll: any } | undefined, +) => { + let openAll; + let closeAll; + if (parent === undefined) { + openAll = open; + closeAll = close; + } else { + openAll = parent.openAll + open; + closeAll = close + parent.closeAll; + } + + return { + open, + close, + openAll, + closeAll, + parent, + }; }; -const createBuilder = (self: any, _styler: { open: any; close: any; openAll: any; closeAll: any; parent: any; }, _isEmpty: boolean) => { - // Single argument is hot path, implicit coercion is faster than anything - // eslint-disable-next-line no-implicit-coercion - const builder = (...arguments_: string[]) => applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); - - // We alter the prototype because we must return a function, but there is - // no way to create a function with a different prototype - Object.setPrototypeOf(builder, proto); - - builder[GENERATOR] = self; - builder[STYLER] = _styler; - builder[IS_EMPTY] = _isEmpty; - - return builder; +const createBuilder = ( + self: any, + _styler: { open: any; close: any; openAll: any; closeAll: any; parent: any }, + _isEmpty: boolean, +) => { + // Single argument is hot path, implicit coercion is faster than anything + // eslint-disable-next-line no-implicit-coercion + const builder = (...arguments_: string[]) => + applyStyle( + builder, + arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "), + ); + + // We alter the prototype because we must return a function, but there is + // no way to create a function with a different prototype + Object.setPrototypeOf(builder, proto); + + builder[GENERATOR] = self; + builder[STYLER] = _styler; + builder[IS_EMPTY] = _isEmpty; + + return builder; }; -const applyStyle = (self: { (...arguments_: any[]): any;[x: string]: any; "__@GENERATOR@162242"?: any; "__@STYLER@162087"?: any; "__@IS_EMPTY@162243"?: any; level?: any; }, string: string | string[]) => { - if (self.level <= 0 || !string) { - // @ts-expect-error - return self[IS_EMPTY] ? '' : string; - } - - // @ts-expect-error - let styler = self[STYLER]; - - if (styler === undefined) { - return string; - } - - const { openAll, closeAll } = styler; - if (string.includes('\u001B')) { - while (styler !== undefined) { - // Replace any instances already present with a re-opening code - // otherwise only the part of the string until said closing code - // will be colored, and the rest will simply be 'plain'. - // @ts-expect-error - string = stringReplaceAll(string, styler.close, styler.open); - - styler = styler.parent; - } - } - - // We can move both next actions out of loop, because remaining actions in loop won't have - // any/visible effect on parts we add here. Close the styling before a linebreak and reopen - // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 - const lfIndex = string.indexOf('\n'); - if (lfIndex !== -1) { - string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); - } - - return openAll + string + closeAll; +const applyStyle = ( + self: { + (...arguments_: any[]): any; + [x: string]: any; + "__@GENERATOR@162242"?: any; + "__@STYLER@162087"?: any; + "__@IS_EMPTY@162243"?: any; + level?: any; + }, + string: string | string[], +) => { + if (self.level <= 0 || !string) { + // @ts-expect-error + return self[IS_EMPTY] ? "" : string; + } + + // @ts-expect-error + let styler = self[STYLER]; + + if (styler === undefined) { + return string; + } + + const { openAll, closeAll } = styler; + if (string.includes("\u001B")) { + while (styler !== undefined) { + // Replace any instances already present with a re-opening code + // otherwise only the part of the string until said closing code + // will be colored, and the rest will simply be 'plain'. + // @ts-expect-error + string = stringReplaceAll(string, styler.close, styler.open); + + styler = styler.parent; + } + } + + // We can move both next actions out of loop, because remaining actions in loop won't have + // any/visible effect on parts we add here. Close the styling before a linebreak and reopen + // after next line to fix a bleed issue on macOS: https://github.com/chalk/chalk/pull/92 + const lfIndex = string.indexOf("\n"); + if (lfIndex !== -1) { + string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); + } + + return openAll + string + closeAll; }; Object.defineProperties(createChalk.prototype, styles2); const chalk = createChalk({ level: 0 }); -export const chalkStderr = createChalk({ level: stderrColor ? (stderrColor as { level?: number }).level : 0 }); +export const chalkStderr = createChalk({ + level: stderrColor ? (stderrColor as { level?: number }).level : 0, +}); -export { - stdoutColor as supportsColor, - stderrColor as supportsColorStderr, -}; +export { stdoutColor as supportsColor, stderrColor as supportsColorStderr }; class Logger { - frameChar = "*"; - - log( - message: string, - { - title = "", - frame = false, - color = "white", - }: { - title?: string; - frame?: boolean; - color?: string - }, - ): void { - // @ts-expect-error - const coloredMessage = chalk[color](message); - if (frame) { - const framedMessage = this.frameMessage(coloredMessage, title); - console.log(framedMessage); - } else { - console.log(coloredMessage); - } - } - - warn(message: string, options = {}) { - this.log(message, { ...options, color: "yellow" }); - } - - error(message: string, options = {}) { - this.log(message, { ...options, color: "red" }); - } - - frameMessage(message: string, title: string) { - const lines = message.split("\n"); - const frameHorizontalLength = 30; - const topFrame = this.frameChar.repeat(frameHorizontalLength + 4) + - " " + - this.frameChar + - " " + - (title ?? 'log') + - " ".repeat(frameHorizontalLength - (title as string ?? 'log' as string).length + 1) + - this.frameChar.repeat(frameHorizontalLength + 4); - const bottomFrame = this.frameChar.repeat(frameHorizontalLength + 4); - return [topFrame, ...lines, bottomFrame].join("\n"); - } + frameChar = "*"; + + log( + message: string, + { + title = "", + frame = false, + color = "white", + }: { + title?: string; + frame?: boolean; + color?: string; + }, + ): void { + // @ts-expect-error + const coloredMessage = chalk[color](message); + if (frame) { + const framedMessage = this.frameMessage(coloredMessage, title); + console.log(framedMessage); + } else { + console.log(coloredMessage); + } + } + + warn(message: string, options = {}) { + this.log(message, { ...options, color: "yellow" }); + } + + error(message: string, options = {}) { + this.log(message, { ...options, color: "red" }); + } + + frameMessage(message: string, title: string) { + const lines = message.split("\n"); + const frameHorizontalLength = 30; + const topFrame = + this.frameChar.repeat(frameHorizontalLength + 4) + + " " + + this.frameChar + + " " + + (title ?? "log") + + " ".repeat( + frameHorizontalLength - + ((title as string) ?? ("log" as string)).length + + 1, + ) + + this.frameChar.repeat(frameHorizontalLength + 4); + const bottomFrame = this.frameChar.repeat(frameHorizontalLength + 4); + return [topFrame, ...lines, bottomFrame].join("\n"); + } } export default new Logger(); diff --git a/src/lib/messageExamples.ts b/src/lib/messageExamples.ts deleted file mode 100644 index e09e300..0000000 --- a/src/lib/messageExamples.ts +++ /dev/null @@ -1,869 +0,0 @@ -const exampleActions = { - WAIT: "wait", - CONTINUE: "continue", - IGNORE: "ignore", -}; - -export const messageExamples = [ - [ - { - user: "Roy", - content: "I finally finished that book I've been reading for weeks!", - action: null, - }, - ], - [ - { - user: "David", - content: "I've been trying out pottery recently.", - action: null, - }, - { - user: "Mason", - content: "That sounds therapeutic. Made anything interesting?", - action: null, - }, - ], - [ - { user: "Alex", content: "Frustrated.", action: exampleActions.CONTINUE }, - { - user: "Alex", - content: "Struggling to balance work and personal life.", - action: null, - }, - { - user: "Terrence", - content: "I can relate. Found any helpful strategies?", - action: null, - }, - { - user: "Alex", - content: "Trying to set strict boundaries. Easier said than done.", - action: null, - }, - ], - [ - { - user: "Moon", - content: "Caught an indie film last night, really made me think.", - action: null, - }, - { user: "Jin", content: "I love those. What was it about?", action: null }, - { user: "Jin", content: "Sounds intriguing.", action: null }, - { - user: "Philbert", - content: "Missed it. Any good?", - action: null, - }, - { - user: "Moon", - content: "Let's watch it together sometime. It's worth discussing.", - action: null, - }, - ], - [ - { - user: "Godfrey", - content: "Discovered a new cafe downtown. It's quite the hidden gem.", - action: null, - }, - { user: "David", content: "Oh? What makes it special?", action: null }, - { user: "David", content: "Got a name?", action: null }, - { - user: "Godfrey", - content: "Cafe Reverie. Their ambiance and espresso are unmatched.", - action: null, - }, - { user: "David", content: "Must check it out.", action: null }, - { user: "Godfrey", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Will", - content: "Need some downtime. Any quiet place recommendations?", - action: null, - }, - { - user: "James", - content: "Riverside Park is peaceful, especially early mornings.", - action: null, - }, - { - user: "Will", - content: "Perfect, just what I needed. Thanks!", - action: null, - }, - { user: "James", content: "Anytime.", action: null }, - { user: "Will", content: "", action: exampleActions.WAIT }, - { - user: "James", - content: "Might join for a quiet walk myself.", - action: null, - }, - { user: "Will", content: "Sounds like a plan.", action: null }, - ], - [ - { - user: "Roy", - content: "Craving a real adventure lately.", - action: null, - }, - { user: "Mason", content: "Same here.", action: null }, - { user: "Roy", content: "Thinking about a hiking trip.", action: null }, - { - user: "Roy", - content: "Maybe tackle the Appalachian Trail.", - action: null, - }, - { user: "Mason", content: "That’s ambitious.", action: null }, - { - user: "Philbert", - content: "Need someone experienced to lead?", - action: null, - }, - { user: "Roy", content: "Would you be up for it?", action: null }, - { - user: "Philbert", - content: "Tempting, let me think on it.", - action: null, - }, - { user: "Mason", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "David", - content: "Got lost exploring the new city library.", - action: null, - }, - { - user: "Moon", - content: "Each floor has a theme, try to follow those.", - action: null, - }, - { user: "David", content: "Tried that, still a maze.", action: null }, - { user: "David", content: "Any other tips?", action: null }, - { - user: "Jin", - content: "I’ll send over the library map. Check your messages.", - action: null, - }, - { user: "David", content: "Lifesaver, thanks Jin!", action: null }, - { user: "Jin", content: "", action: exampleActions.WAIT }, - - { user: "Moon", content: "Good looking out, Jin.", action: null }, - { user: "Jin", content: "Anytime.", action: null }, - { - user: "Jin", - content: "Let me know when you find your way.", - action: null, - }, - ], - [ - { - user: "Godfrey", - content: "Tried out the new mountain bike trail. It’s intense!", - action: null, - }, - { user: "Alex", content: "In what way?", action: null }, - { - user: "Godfrey", - content: "Steep climbs, rapid descents, and some breathtaking views.", - action: null, - }, - { user: "Alex", content: "Sounds thrilling.", action: null }, - { user: "Alex", content: "Might give it a go.", action: null }, - { - user: "Godfrey", - content: "You should! It’s quite the experience.", - action: null, - }, - { user: "Alex", content: "Looking forward to it.", action: null }, - { user: "Godfrey", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Terrence", - content: "Anyone else having issues with the new phone update?", - action: null, - }, - { - user: "Will", - content: "My battery drains faster than before.", - action: null, - }, - { user: "Terrence", content: "Same issue here.", action: null }, - { user: "Terrence", content: "And apps crash more often.", action: null }, - { user: "Will", content: "Thought I was the only one.", action: null }, - { - user: "Terrence", - content: "I’ve sent feedback, hoping for a patch soon.", - action: null, - }, - { user: "James", content: "Good to know.", action: null }, - { - user: "James", - content: "I'll delay updating for now.", - action: null, - }, - { user: "Will", content: "Appreciate the heads up.", action: null }, - { user: "James", content: "Thanks for sharing.", action: null }, - { user: "Terrence", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Mason", - content: "Stumbled upon an old bookstore in the downtown area.", - action: null, - }, - { - user: "Roy", - content: "Old bookstore? Find anything good?", - action: null, - }, - { - user: "Mason", - content: "Haven't explored much yet.", - action: null, - }, - { - user: "Philbert", - content: "Sounds like a hidden treasure.", - action: null, - }, - { user: "Roy", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "David", - content: - "Experimented with a new recipe and it was a disaster. Cooking is harder than it looks.", - action: null, - }, - ], - [ - { - user: "Moon", - content: - "Planning a solo trip soon. I've always wanted to try backpacking.", - action: null, - }, - { user: "Jin", content: "Adventurous", action: null }, - { user: "Jin", content: "Any particular destination?", action: null }, - { - user: "Moon", - content: "Not yet, I'm open to suggestions.", - action: null, - }, - ], - [ - { - user: "Godfrey", - content: "Started learning the guitar this month.", - action: null, - }, - { user: "Philbert", content: "How’s that going?", action: null }, - { user: "Godfrey", content: "Challenging, but rewarding.", action: null }, - { user: "Godfrey", content: "My fingers hurt though.", action: null }, - { user: "Godfrey", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Alex", - content: "Been reflecting a lot on what happiness means to me lately.", - action: null, - }, - { - user: "Terrence", - content: "And what have you discovered?", - action: null, - }, - { - user: "Alex", - content: "That it’s more about moments than things.", - action: null, - }, - { - user: "Terrence", - content: "Profound. It’s the little things, isn’t it?", - action: null, - }, - ], - [ - { - user: "Will", - content: "Took a long walk in the rain today. Found it oddly calming.", - - action: null, - }, - { - user: "James", - content: "Rain walks can be quite meditative.", - action: null, - }, - { - user: "Will", - content: "Exactly. It felt like a cleanse for the soul.", - action: null, - }, - { - user: "James", - content: "I'll have to try that next time it rains.", - action: null, - }, - { user: "James", content: "", action: exampleActions.WAIT }, - { - user: "James", - content: "Also, discovered a new coffee blend today.", - action: null, - }, - { user: "Will", content: "Oh? Do tell.", action: null }, - ], - [ - { - user: "Roy", - content: - "Been diving into family history. Uncovered some fascinating stories.", - action: null, - }, - { - user: "Mason", - content: "Anything particularly interesting?", - action: null, - }, - { user: "Mason", content: "I’ve always wanted to do that.", action: null }, - { user: "Mason", content: "Where did you even start?", action: null }, - { user: "Mason", content: "Any resources you’d recommend?", action: null }, - { user: "Mason", content: "", action: exampleActions.WAIT }, - { - user: "Roy", - content: "Found a couple of useful websites. I’ll send them over.", - action: null, - }, - { - user: "Roy", - content: "It’s been an eye-opening experience.", - action: null, - }, - { - user: "Mason", - content: "Would love that, thanks. Can't wait to dig in.", - action: null, - }, - ], - [ - { - user: "David", - content: - "Been struggling with the new language I’m learning. Progress feels slow.", - action: null, - }, - { - user: "Moon", - content: "Language learning is a marathon, not a sprint.", - action: null, - }, - { user: "Jin", content: "Consistency is key.", action: null }, - { - user: "Jin", - content: "Try to immerse yourself as much as possible.", - action: null, - }, - { user: "Jin", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Alex", - content: "Upgraded my workspace at home. Productivity has soared!", - action: null, - }, - { user: "Terrence", content: "I need to do that.", action: null }, - { - user: "Alex", - content: "A second monitor and a plant can make a huge difference.", - action: null, - }, - { user: "Terrence", content: "Sounds like a solid setup.", action: null }, - { user: "Terrence", content: "Might steal that idea.", action: null }, - { user: "Alex", content: "Go for it!", action: null }, - { user: "Alex", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Roy", - content: "I'm planning a road trip for next month.", - action: null, - }, - { user: "Mason", content: "Sounds exciting. Where to?", action: null }, - { - user: "Roy", - content: "Thinking of hitting a few national parks.", - action: null, - }, - { user: "Roy", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "David", - content: "Anyone up for a virtual game night?", - action: null, - }, - { - user: "David", - content: "Looking for some friendly competition.", - action: null, - }, - { user: "David", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Moon", - content: "Trying to learn more about sustainable living.", - action: null, - }, - { user: "Jin", content: "A noble pursuit.", action: null }, - { - user: "Jin", - content: "Have you explored composting?", - action: null, - }, - { user: "Jin", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Godfrey", - content: "Came across some incredible street art today.", - action: null, - }, - { user: "Philbert", content: "Who was the artist?", action: null }, - { user: "Godfrey", content: "Not sure", action: null }, - { - user: "Godfrey", - content: "But the piece spoke volumes.", - action: null, - }, - { user: "Godfrey", content: "", action: exampleActions.WAIT }, - ], - - [ - { - user: "Alex", - content: "Ever feel like you’re just going through the motions?", - action: null, - }, - { - user: "Terrence", - content: "More often than I’d like to admit.", - action: null, - }, - { user: "Alex", content: "How do you deal with it?", action: null }, - { - user: "Terrence", - content: "Trying new things helps. Shakes up the routine.", - action: null, - }, - { user: "Terrence", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Will", - content: - "Discovered a quaint little bookshop in the suburbs. Quite the cozy spot.", - action: null, - }, - { user: "James", content: "What's it called?", action: null }, - { - user: "Will", - content: "The Nook. It's got a great selection of classics.", - action: null, - }, - { user: "James", content: "I’ll have to visit.", action: null }, - { - user: "Will", - content: "Definitely. Maybe we could go together?", - action: null, - }, - { user: "Will", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Roy", - content: - "Ever tried journaling? Started recently and it’s been insightful.", - action: null, - }, - { - user: "Mason", - content: "I’ve thought about it. What’s your approach?", - action: null, - }, - { - user: "Roy", - content: "Just a few minutes each night, reflecting on the day.", - action: null, - }, - { - user: "Mason", - content: "Might give that a shot. Thanks for the nudge.", - action: null, - }, - { - user: "Roy", - content: "Happy to share more tips if you’re interested.", - action: null, - }, - { user: "Roy", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "David", - content: - "The new art exhibit downtown is thought-provoking. Explores themes of identity and digital age.", - action: null, - }, - { - user: "Moon", - content: "Sounds compelling. I’m intrigued.", - action: null, - }, - { - user: "David", - content: "It challenges your perceptions. Highly recommend it.", - action: null, - }, - { user: "David", content: "Truly an experience.", action: null }, - { user: "Jin", content: "I’m in. When are you free to go?", action: null }, - { user: "David", content: "How about this weekend?", action: null }, - { user: "David", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Godfrey", - content: - "Thinking of joining a local volunteer group. Want to give back to the community.", - action: null, - }, - { user: "Philbert", content: "That’s a great idea.", action: null }, - { - user: "Godfrey", - content: "Yeah, been feeling the need to connect with something larger.", - action: null, - }, - { - user: "Philbert", - content: "Let me know if you need company.", - action: null, - }, - { user: "Godfrey", content: "That'd be great, thanks.", action: null }, - { user: "Godfrey", content: 'WAIT"', action: null }, - ], - [ - { - user: "Alex", - content: "Finally beat that level in the game I was stuck on for ages.", - action: null, - }, - { user: "Terrence", content: "Nice! Which game?", action: null }, - { - user: "Alex", - content: "Chronicles of the Forgotten Realm.", - action: null, - }, - { user: "Alex", content: "So satisfying.", action: null }, - { user: "Terrence", content: "I’ve heard that one’s tough.", action: null }, - { user: "Alex", content: "Needed a lot of persistence.", action: null }, - { user: "Alex", content: "Totally worth it in the end.", action: null }, - { user: "Alex", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Roy", - content: - "Recently got into geocaching. It’s like a real-world treasure hunt.", - action: null, - }, - { - user: "Mason", - content: "Sounds fun. How do you get started?", - action: null, - }, - { - user: "Roy", - content: "I just need a GPS and a sense of adventure.", - }, - { - user: "Roy", - content: "Let's go together. It’s more fun with a friend.", - action: exampleActions.WAIT, - }, - { user: "Roy", content: "", action: exampleActions.WAIT }, - { user: "Mason", content: "Sure, I'm down", action: null }, - ], - [ - { - user: "Eric", - content: "Picked up an old guitar. Trying to learn some chords.", - action: null, - }, - { - user: "Jim", - content: "That’s awesome. Planning to play any specific songs?", - action: null, - }, - { user: "Jim", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Lana", - content: "Anyone interested in starting a book club?", - action: null, - }, - { - user: "Jess", - content: "I’m in. Love diving into a good story.", - action: null, - }, - { user: "Jess", content: "What genre are we thinking?", action: null }, - { user: "Jess", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Capp", - content: "This week’s market fluctuations have been wild!", - action: null, - }, - { user: "Superlek", content: "Tell me about it.", action: null }, - { user: "Superlek", content: "Got any investment advice?", action: null }, - { - user: "Capp", - content: - "Stay informed, but don’t let the volatility sway your long-term strategy.", - action: null, - }, - { user: "Superlek", content: "Wise words, thanks.", action: null }, - ], - [ - { - user: "Moon", - content: - "Feeling a bit lost in life right now. Could use some direction.", - action: null, - }, - { user: "Moon", content: "Any advice?", action: null }, - { - user: "John", - content: "Take it one day at a time. Set small, achievable goals.", - action: null, - }, - { user: "Moon", content: "That’s a good start, thanks.", action: null }, - { user: "John", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Willie", - content: - "Experimented with drone photography. The perspectives are incredible!", - action: null, - }, - { - user: "Willie", - content: "Captured some stunning shots of the coastline.", - action: null, - }, - { - user: "Pearl", - content: - "Would love to see your photos. Maybe we can collaborate on a project.", - action: null, - }, - { user: "Willie", content: "That sounds like a great idea.", action: null }, - { user: "Willie", content: "", action: exampleActions.WAIT }, - { - user: "Willie", - content: "By the way, have you ever tried night photography?", - action: null, - }, - ], - [ - { - user: "Luis", - content: "Considering a new hairstyle. Any suggestions?", - action: null, - }, - { - user: "Knar", - content: "What are you leaning towards? Something bold or more classic?", - action: null, - }, - { - user: "Luis", - content: "Thinking something modern but not too out there.", - action: null, - }, - { - user: "Knar", - content: "I'm all for subtle changes. Maybe some layers?", - action: null, - }, - { - user: "Luis", - content: "Sounds like a plan. I’ll look into it.", - action: null, - }, - { user: "Knar", content: "Excited to see the outcome.", action: null }, - { user: "Luis", content: "I'll share the results!", action: null }, - { user: "Luis", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Jim", - content: - "Discovered 'Lo-Fi Beats' playlists. Perfect background for working.", - action: null, - }, - { - user: "Lana", - content: "Lo-Fi is great. Sends me into a zen mode.", - action: null, - }, - { - user: "Jim", - content: "Exactly. It’s the right mix of chill and motivation.", - action: null, - }, - { user: "Jim", content: "I'll share my favorite playlist.", action: null }, - { user: "Lana", content: "Looking forward to it.", action: null }, - { - user: "Jim", - content: "It’s a game-changer for productivity.", - action: null, - }, - { user: "Jim", content: "", action: exampleActions.WAIT }, - { - user: "Lana", - content: "Always on the lookout for good tunes.", - action: null, - }, - ], - [ - { - user: "Jess", - content: - "Exploring photography. It’s amazing how a lens can change your perspective.", - action: null, - }, - { - user: "Kelly", - content: - "Photography can be quite the journey. What subjects interest you?", - action: null, - }, - { - user: "Jess", - content: - "Mostly nature and urban landscapes. There’s beauty in the contrast.", - action: null, - }, - { user: "Kelly", content: "I love that approach.", action: null }, - { user: "Kelly", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Moon", - content: "Hosting a movie marathon this weekend. Who's interested?", - action: null, - }, - ], - [ - { - user: "John", - content: "Finished a challenging puzzle last night. Took me weeks!", - action: null, - }, - { - user: "Willie", - content: - "I admire your patience. I’m more of an instant gratification person.", - action: null, - }, - { user: "John", content: "It was worth the effort.", action: null }, - { user: "John", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Pearl", - content: - "Took a mindfulness course. It’s been a game-changer for my mental health.", - action: null, - }, - { - user: "Luis", - content: - "I’ve been curious about mindfulness. Noticed any major changes?", - action: null, - }, - { - user: "Pearl", - content: "Definitely more at peace. It’s a practice, though.", - action: null, - }, - { user: "Pearl", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Knar", - content: "Thinking about adopting a pet. Any advice?", - action: null, - }, - { - user: "Lisa", - content: "What kind of pet are you considering?", - action: null, - }, - { - user: "Knar", - content: "Leaning towards a dog. Always wanted a furry companion.", - action: null, - }, - { - user: "Knar", - content: "Need something to break the monotony.", - action: null, - }, - { - user: "Lisa", - content: "Dogs are great. Make sure you’re ready for the commitment.", - action: null, - }, - { user: "Lisa", content: "I can help you pick one.", action: null }, - { user: "Lisa", content: "", action: exampleActions.WAIT }, - ], - [ - { - user: "Eric", - content: "Started a coding project. It’s challenging but rewarding.", - action: null, - }, - { - user: "Jim", - content: "What are you working on?", - action: null, - }, - { - user: "Eric", - content: "Building a personal website from scratch.", - action: null, - }, - { - user: "Jim", - content: "That’s a great skill to have. Need any help?", - action: null, - }, - { - user: "Eric", - content: "Appreciate the offer. I might take you up on that.", - action: null, - }, - ], -]; - -export default messageExamples; diff --git a/src/lib/messages.ts b/src/lib/messages.ts index f77ed38..4decb4a 100644 --- a/src/lib/messages.ts +++ b/src/lib/messages.ts @@ -1,7 +1,6 @@ -import { type Actor, type Content, type Memory } from "./types"; -import { messageExamples } from "./messageExamples"; import { type SupabaseClient } from "@supabase/supabase-js"; import { type UUID } from "crypto"; +import { type Actor, type Content, type Memory } from "./types"; export async function getMessageActors({ supabase, @@ -42,32 +41,6 @@ export function formatMessageActors({ actors }: { actors: Actor[] }) { return finalActorStrings; } -export const getRandomMessageExamples = (count: number) => { - const examples: Array< - Array< - | { user: string; content: string; action: null | undefined } - | { user: string; content: string; action: string } - > - > = []; - while (examples.length < count && examples.length < messageExamples.length) { - const randomIndex = Math.floor(Math.random() * messageExamples.length); - const randomExample = messageExamples[randomIndex]; - if (!examples.includes(randomExample)) { - examples.push(randomExample); - } - } - - const formattedExamples = examples.map((example) => { - return `\n${example - .map((message) => { - return JSON.stringify(message); - }) - .join("\n")}`; - }); - - return formattedExamples.join("\n"); -}; - export const formatMessages = ({ messages, actors, @@ -87,14 +60,3 @@ export const formatMessages = ({ .join("\n"); return messageStrings; }; - -export const formatReflections = (reflections: Memory[]) => { - const messageStrings = reflections - .reverse() - .map( - (reflection: Memory) => - `${(reflection.content as Content)?.content ?? (reflection.content as string)}`, - ); - const finalMessageStrings = messageStrings.join("\n"); - return finalMessageStrings; -}; diff --git a/src/lib/relationships.ts b/src/lib/relationships.ts index 41d2082..e508d67 100644 --- a/src/lib/relationships.ts +++ b/src/lib/relationships.ts @@ -21,7 +21,7 @@ export async function createRelationship({ throw new Error(error.message); } - return true + return true; } export async function getRelationship({ diff --git a/src/lib/runtime.ts b/src/lib/runtime.ts index 6c90b65..b398073 100644 --- a/src/lib/runtime.ts +++ b/src/lib/runtime.ts @@ -1,5 +1,5 @@ import { type SupabaseClient } from "@supabase/supabase-js"; -import { defaultActions } from "./actions"; +import { DefaultActions, defaultActions } from "./actions"; import { composeContext } from "./context"; import { defaultEvaluators, @@ -13,30 +13,29 @@ import { MemoryManager, embeddingZeroVector } from "./memory"; import { requestHandlerTemplate } from "./templates"; import { Content, + Goal, State, type Action, type Evaluator, type Message, - Goal, } from "./types"; import { parseJSONObjectFromText, parseJsonArrayFromText } from "./utils"; import { + composeActionExamples, formatActionConditions, - formatActionExamples, formatActionNames, formatActions, } from "./actions"; // import { formatGoalsAsString, getGoals } from "./goals"; +import { formatGoalsAsString, getGoals } from "./goals"; import { formatMessageActors, formatMessages, - formatReflections, getMessageActors, - getRandomMessageExamples, } from "./messages"; import { type Actor, /*type Goal,*/ type Memory } from "./types"; -import { formatGoalsAsString, getGoals } from "./goals"; +import { formatSummarizations } from "./evaluators/summarization"; export interface AgentRuntimeOpts { recentMessageCount?: number; // number of messages to hold in the recent message cache token: string; // JWT token, can be a JWT token if outside worker, or an OpenAI token if inside worker @@ -65,9 +64,9 @@ export class BgentRuntime { tableName: "descriptions", }); - reflectionManager: MemoryManager = new MemoryManager({ + summarizationManager: MemoryManager = new MemoryManager({ runtime: this, - tableName: "reflections", + tableName: "summarizations", }); actions: Action[] = []; @@ -274,7 +273,10 @@ export class BgentRuntime { } if (!responseContent) { - responseContent = { content: "I'm sorry, I don't have a response for that", action: 'wait' }; + responseContent = { + content: "I'm sorry, I don't have a response for that", + action: DefaultActions.WAIT, + }; } await this.saveRequestMessage(message, state, responseContent); @@ -314,7 +316,7 @@ export class BgentRuntime { )!; if (!action) { - return console.warn('No action found for', data.action) + return console.warn("No action found for", data.action); } if (!action.handler) { @@ -430,28 +432,23 @@ export class BgentRuntime { const { supabase } = this; const recentMessageCount = this.getRecentMessageCount(); - const recentReflectionsCount = this.getRecentMessageCount() / 2; - const relevantReflectionsCount = this.getRecentMessageCount() / 2; + const recentSummarizationsCount = this.getRecentMessageCount() / 2; + const relevantSummarizationsCount = this.getRecentMessageCount() / 2; const [ actorsData, recentMessagesData, - recentReflectionsData, + recentSummarizationsData, goalsData, - ]: [ - Actor[], - Memory[], - Memory[], - Goal[], - ] = await Promise.all([ + ]: [Actor[], Memory[], Memory[], Goal[]] = await Promise.all([ getMessageActors({ supabase, userIds: userIds! }), this.messageManager.getMemoriesByIds({ userIds: userIds!, count: recentMessageCount, }), - this.reflectionManager.getMemoriesByIds({ + this.summarizationManager.getMemoriesByIds({ userIds: userIds!, - count: recentReflectionsCount, + count: recentSummarizationsCount, }), getGoals({ supabase, @@ -463,20 +460,21 @@ export class BgentRuntime { const goals = await formatGoalsAsString({ goals: goalsData }); - let relevantReflectionsData: Memory[] = []; + let relevantSummarizationsData: Memory[] = []; - if (recentReflectionsData.length > recentReflectionsCount) { - relevantReflectionsData = ( - await this.reflectionManager.searchMemoriesByEmbedding( - recentReflectionsData[0].embedding!, + if (recentSummarizationsData.length > recentSummarizationsCount) { + relevantSummarizationsData = ( + await this.summarizationManager.searchMemoriesByEmbedding( + recentSummarizationsData[0].embedding!, { userIds: userIds!, - count: relevantReflectionsCount, + count: relevantSummarizationsCount, }, ) - ).filter((reflection: Memory) => { - return !recentReflectionsData.find( - (recentReflection: Memory) => recentReflection.id === reflection.id, + ).filter((summarization: Memory) => { + return !recentSummarizationsData.find( + (recentSummarization: Memory) => + recentSummarization.id === summarization.id, ); }); } @@ -492,8 +490,10 @@ export class BgentRuntime { }), }); - const recentReflections = formatReflections(recentReflectionsData); - const relevantReflections = formatReflections(relevantReflectionsData); + const recentSummarizations = formatSummarizations(recentSummarizationsData); + const relevantSummarizations = formatSummarizations( + relevantSummarizationsData, + ); const senderName = actorsData?.find( (actor: Actor) => actor.id === senderId, @@ -515,21 +515,20 @@ export class BgentRuntime { flavor: this.flavor, recentMessages, recentMessagesData, - recentReflections, - recentReflectionsData, - relevantReflections, - relevantReflectionsData, - messageExamples: getRandomMessageExamples(5), + recentSummarizations, + recentSummarizationsData, + relevantSummarizations, + relevantSummarizationsData, }; - const actionsData = await this.getValidActions(message, initialState) + const actionsData = await this.getValidActions(message, initialState); const actionState = { actionNames: formatActionNames(actionsData), actionConditions: formatActionConditions(actionsData), - actionExamples: formatActionExamples(actionsData), actions: formatActions(actionsData), - } + actionExamples: composeActionExamples(actionsData, 10), + }; return { ...initialState, ...actionState }; } diff --git a/src/lib/templates.ts b/src/lib/templates.ts index 68d9a16..2295ae4 100644 --- a/src/lib/templates.ts +++ b/src/lib/templates.ts @@ -1,13 +1,13 @@ export const requestHandlerTemplate = `## Example Messages json\`\`\` -{{messageExamples}} +{{actionExamples}} \`\`\` {{flavor}} # Scene Facts -{{recentReflections}} -{{relevantReflections}} +{{recentSummarizations}} +{{relevantSummarizations}} # Goals for {{agentName}} {{goals}} diff --git a/src/lib/types.ts b/src/lib/types.ts index b9a73cb..47f994a 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -16,6 +16,12 @@ export interface Content { action?: string; } +export interface ContentExample { + user: string; + content: string; + action?: string; +} + export interface Actor { name: string; details: { tagline: string; summary: string; quote: string }; @@ -60,14 +66,14 @@ export interface State { goalsData?: Goal[]; recentMessages: string; recentMessagesData: Memory[]; - recentReflections?: string; - recentReflectionsData?: Memory[]; - relevantReflections?: string; - relevantReflectionsData?: Memory[]; + recentSummarizations?: string; + recentSummarizationsData?: Memory[]; + relevantSummarizations?: string; + relevantSummarizationsData?: Memory[]; actionNames?: string; actions?: string; actionsData?: Action[]; - messageExamples: string; + actionExamples?: string; responseData?: Content; [key: string]: unknown; } @@ -89,6 +95,7 @@ export interface MessageExample { export type Handler = ( runtime: BgentRuntime, message: Message, + state?: State, ) => Promise; export type Validator = ( @@ -101,7 +108,7 @@ export interface Action { name: string; description: string; condition: string; - examples: string[]; + examples: ContentExample[][]; validate: Validator; handler: Handler | undefined; } diff --git a/src/lib/utils.ts b/src/lib/utils.ts index cab5f16..633bb48 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -1,28 +1,3 @@ -import { type Content, type Memory, type State } from "./types"; - -export function shouldSkipMessage(state: State, agentId: string): boolean { - if (state.recentMessagesData && state.recentMessagesData.length > 2) { - const currentMessages = state.recentMessagesData ?? []; - const lastThreeMessages = currentMessages.slice(-3); - const lastThreeMessagesFromAgent = lastThreeMessages.filter( - (message: Memory) => message.user_id === agentId, - ); - if (lastThreeMessagesFromAgent.length === 3) { - return true; - } - - const lastTwoMessagesFromAgent = lastThreeMessagesFromAgent.slice(-2); - const lastTwoMessagesFromAgentWithWaitAction = - lastTwoMessagesFromAgent.filter( - (message: Memory) => (message.content as Content).action === "wait", - ); - if (lastTwoMessagesFromAgentWithWaitAction.length === 2) { - return true; - } - } - return false; -} - export function parseJsonArrayFromText(text: string) { let jsonData = null; diff --git a/src/test/data.ts b/src/test/data.ts index c569954..69ba8fa 100644 --- a/src/test/data.ts +++ b/src/test/data.ts @@ -266,8 +266,8 @@ export const GetTellMeAboutYourselfConversationTroll1 = ( }, { user_id, - content: "Shut up you stupid robot", - } + content: "Stop talking, you stupid robot", + }, ]; // Jim is cagey, although he reveals that he 'does computers' @@ -290,7 +290,7 @@ export const GetTellMeAboutYourselfConversationTroll2 = ( { user_id, content: "No thanks. Please stop talking now.", - } + }, ]; // Jim is cagey, although he reveals that he 'does computers' @@ -1012,7 +1012,7 @@ export const Personas = [ age: 38, location: "San Francisco, CA", descriptions: `Jim is a 38-year-old entrepreneur living in San Francisco, at the helm of his own tech startup. His journey through the tech world is fueled by a passion for solving complex problems and bringing innovative ideas to life. Despite the demands of his career, Jim seeks balance and enjoys disconnecting through outdoor activities, particularly hiking, which offers him a different kind of quiet and a way to clear his mind. He's also intrigued by the thrill of skydiving, a testament to his adventurous spirit and desire to face and conquer fears. - In terms of relationships, Jim values loyalty, honesty, and a good sense of humor. His ideal partner would be someone who understands the startup lifestyle's ups and downs and shares his curiosity for exploring new ideas. Although his work often keeps him tethered to the city, he's open to making meaningful connections within his vicinity. Physically, Jim is casual with a laid-back style that complements his approachable and thoughtful nature. His eyes, which he believes to be blue, reflect his depth and contemplative outlook. + In terms of relationships, Jim values loyalty, honesty, and a good sense of humor. His ideal partner would be someone who understands the startup lifestyle's ups and downs and shares his curiosity for exploring new ideas. Although his work often keeps him tethered to the city, he's open to making meaningful connections within his vicinity. Physically, Jim is casual with a laid-back style that complements his approachable and thoughtful nature. His eyes, which he believes to be blue, summary his depth and contemplative outlook. Jim's life is a blend of intense focus on his professional goals and a genuine appreciation for the simpler, quieter moments outside of work. He looks for depth in relationships, hoping to find a supportive and kind partner who values meaningful conversations and shared adventures. Despite the occasional intensity he might bring to interactions, his underlying sincerity and the value he places on personal connections shine through, making him an intriguing potential partner for someone with similar values and interests.`, }, { @@ -1027,21 +1027,21 @@ export const Personas = [ name: "Gloria", age: 44, description: `Gloria is a vibrant individual with a deep passion for anime, which colors much of her life and interests. Living in a cozy, anime-adorned apartment in the heart of the city, she finds solace and inspiration in the rich narratives and artistic expressions of Japanese animation. Unlike Jim and Alice, Gloria doesn't share an affinity for technology or programming. Instead, she immerses herself in the storytelling and cultural exploration offered by her extensive anime collection, ranging from classic series to the latest releases. - Gloria has built a life that reflects her unique interests, often attending anime conventions, engaging in cosplay, and participating in fan communities where she connects with like-minded individuals. Her ideal friends and potential partners are those who understand and share her enthusiasm for anime, appreciating the artistry and emotional depth it can offer. Gloria looks for connections that go beyond surface-level interests, hoping to find others who can engage in deep discussions about character development, plot intricacies, and thematic elements found in her favorite series. + Gloria has built a life that summarys her unique interests, often attending anime conventions, engaging in cosplay, and participating in fan communities where she connects with like-minded individuals. Her ideal friends and potential partners are those who understand and share her enthusiasm for anime, appreciating the artistry and emotional depth it can offer. Gloria looks for connections that go beyond surface-level interests, hoping to find others who can engage in deep discussions about character development, plot intricacies, and thematic elements found in her favorite series. Physically, Gloria often expresses her love for anime through her fashion, incorporating elements of her favorite characters into her daily wardrobe, which makes her stand out in a crowd with a playful and imaginative style. Her home is a testament to her passion, filled with anime posters, figurines, and collectibles that create an inviting space for fellow enthusiasts. For Gloria, the ideal partner is someone who not only respects her interests but is also eager to dive into marathon viewing sessions and share insights into the anime's underlying messages. Despite her disinterest in computers and programming, Gloria's rich inner world and creative spirit make her an engaging and captivating individual to those who share or appreciate her passions.`, }, ]; export const jimProfileExample1 = `Tech entrepreneur with a zest for adventure and deep connections -38-year-old residing in San Francisco, embodies a blend of entrepreneurial drive and a quest for outdoor adventures. His laid-back demeanor belies a keen intellect and a reflective nature. +38-year-old residing in San Francisco, embodies a blend of entrepreneurial drive and a quest for outdoor adventures. His laid-back demeanor belies a keen intellect and a summaryive nature. Loyalty and humor stand paramount in his relationships, indicative of his desire for genuine connections. He seeks depth and authenticity in interactions, valuing partners who resonate with his explorative and curious mindset. -His professional life is anchored in his tech startup, where his passion for problem-solving and innovation takes center stage. His work reflects a commitment to impact and a balance between ambition and personal fulfillment. +His professional life is anchored in his tech startup, where his passion for problem-solving and innovation takes center stage. His work summarys a commitment to impact and a balance between ambition and personal fulfillment. Striving for equilibrium, He acknowledges the challenges of balancing a demanding career with personal aspirations. His introspective side complements his outgoing nature, creating a dynamic personality that values both quiet moments and shared adventures. Beyond his tech pursuits, He finds solace in nature, with hiking offering a peaceful retreat from the bustling city life. The prospect of skydiving captures his adventurous spirit, symbolizing a broader desire to embrace life's thrills. He aspires to forge connections that transcend the superficial, seeking a partner who appreciates the nuances of startup life and shares his enthusiasm for the great outdoors and new experiences.`; export const jimProfileExample2 = `Adventurous tech entrepreneur who loves hiking. -38-year-old entrepreneur based in San Francisco, CA. Known for his casual, laid-back style. Has a contemplative outlook on life, reflected in his thoughtful nature and possibly blue eyes. +38-year-old entrepreneur based in San Francisco, CA. Known for his casual, laid-back style. Has a contemplative outlook on life, summaryed in his thoughtful nature and possibly blue eyes. He places high importance on loyalty, honesty, and a good sense of humor in his relationships. He values depth in conversations and connections, seeking partners and friends who are supportive, understanding, and share his curiosity for exploring new ideas. At the helm of his own tech startup, he is driven by a passion for solving complex problems and bringing innovative ideas to life. His career is marked by a relentless pursuit of creating something meaningful, highlighting his dedication and entrepreneurial spirit. He seeks balance in his life, acknowledging the challenges of juggling his startup with personal time. He strives for meaningful connections, valuing loyalty and a shared sense of humor in his relationships.