diff --git a/.gitignore b/.gitignore index 1ba919c..a6aca18 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,5 @@ build *.njsproj *.sln *.sw? + +models \ No newline at end of file diff --git a/electron.js b/electron.js index 74f5e2f..37b1421 100644 --- a/electron.js +++ b/electron.js @@ -1,5 +1,5 @@ // eslint-disable-next-line -const { app, Menu, BrowserWindow } = require('electron'); +const { app, Menu, BrowserWindow, ipcMain } = require('electron'); // eslint-disable-next-line const path = require('path'); @@ -13,6 +13,12 @@ function createWindow() { minWidth: 560, minHeight: 250, autoHideMenuBar: true, + webPreferences: { + // eslint-disable-next-line + preload: path.join(__dirname, 'preloader', 'index.js'), + nodeIntegration: true, + contextIsolation: true + } }) if(app.isPackaged) { diff --git a/eslint.config.mjs b/eslint.config.mjs index be0ee6d..2cb4974 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -36,4 +36,10 @@ export default [ "react/prop-types": "off" }, }, + { + files: ["preloader/**"], + rules: { + 'no-undef': "off" + } + } ] diff --git a/package.json b/package.json index f4fdd91..7e9d0ee 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@aws-sdk/credential-providers": "^3.650.0", "@huggingface/jinja": "^0.3.0", "@wllama/wllama": "^1.16.0", + "node-llama-cpp": "^3.1.1", "openai": "^4.61.0", "react": "^18.3.1", "react-bootstrap-icons": "^1.11.4", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3cd601e..10dee17 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -20,6 +20,9 @@ importers: '@wllama/wllama': specifier: ^1.16.0 version: 1.16.1 + node-llama-cpp: + specifier: ^3.1.1 + version: 3.1.1(typescript@5.6.2) openai: specifier: ^4.61.0 version: 4.61.0(encoding@0.1.13) @@ -511,6 +514,10 @@ packages: resolution: {integrity: sha512-GLJzso0M07ZncFkrJMIXVU4os6GFbPocD4g8fMQPMGJubf48FtGOsUORH2rtFdXPIPelz8SLBMn8ZRmOTwXm9Q==} engines: {node: '>=18'} + '@huggingface/jinja@0.3.1': + resolution: {integrity: sha512-SbcBWUKDQ76lzlVYOloscUk0SJjuL1LcbZsfQv/Bxxc7dwJMYuS+DAQ+HhVw6ZkTFXArejaX5HQRuCuleYwYdA==} + engines: {node: '>=18'} + '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} @@ -544,6 +551,12 @@ packages: '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} + '@kwsites/file-exists@1.1.1': + resolution: {integrity: sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==} + + '@kwsites/promise-deferred@1.1.1': + resolution: {integrity: sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==} + '@malept/cross-spawn-promise@2.0.0': resolution: {integrity: sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==} engines: {node: '>= 12.13.0'} @@ -552,6 +565,72 @@ packages: resolution: {integrity: sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==} engines: {node: '>= 10.0.0'} + '@node-llama-cpp/linux-arm64@3.1.1': + resolution: {integrity: sha512-rrn1O9zmg8L47e16YlbGI3+Uw1Z8HCTNiBqnz+qcfH2H6HnHd1IenM1CgR9+PVODCnUXE7ErN2moto1XsOxifQ==} + engines: {node: '>=18.0.0'} + cpu: [arm64, x64] + os: [linux] + + '@node-llama-cpp/linux-armv7l@3.1.1': + resolution: {integrity: sha512-fM5dr/wmL4R3rADUOa0SnFRYYpyzsxG0akhg+qBgh0/b1jGwGM6jzBQ9AuhsgfW9tjKdpvpM2GyUDh4tHGHN5w==} + engines: {node: '>=18.0.0'} + cpu: [arm, x64] + os: [linux] + + '@node-llama-cpp/linux-x64-cuda@3.1.1': + resolution: {integrity: sha512-2435gpEI1M0gs8R0/EcpsXwkEtz1hu0waFJjQjck2KNE/Pz+DTw4T7JgWSkAS8uPS7XzzDGBXDuuK1er0ACq3w==} + engines: {node: '>=18.0.0'} + cpu: [x64] + os: [linux] + + '@node-llama-cpp/linux-x64-vulkan@3.1.1': + resolution: {integrity: sha512-iSuaLDsmypv/eASW5DD09FMCCFRKgumpxdB9DHiG8oOd9CLFZle+fxql1TJx3zwtYRrsR7YkfWinjhILYfSIZw==} + engines: {node: '>=18.0.0'} + cpu: [x64] + os: [linux] + + '@node-llama-cpp/linux-x64@3.1.1': + resolution: {integrity: sha512-s3VsBTrVWJgBfV5HruhfkTrnh5ykbuaCXvm1xRMpmMpnkL2tMMOrJJFJJIvrTurtGTxEvbO45O+wLU4wrVlQOw==} + engines: {node: '>=18.0.0'} + cpu: [x64] + os: [linux] + + '@node-llama-cpp/mac-arm64-metal@3.1.1': + resolution: {integrity: sha512-VBVVZhF5zQ31BmmIN/dWG0k4VIWZGar8nDn0/64eLjufkdYGns6hAIssu6IDQ2HBfnq3ENgSgJTpXp7jq9Z2Ig==} + engines: {node: '>=18.0.0'} + cpu: [arm64, x64] + os: [darwin] + + '@node-llama-cpp/mac-x64@3.1.1': + resolution: {integrity: sha512-7UJDsoFpZW3ETsDG623KWZO/pyA1jfVsSPDTJjmotQN1rvXtVqt6cVN/AJ6OjHdoPdEW0u7QxD2nwxY24rRwaQ==} + engines: {node: '>=18.0.0'} + cpu: [x64] + os: [darwin] + + '@node-llama-cpp/win-arm64@3.1.1': + resolution: {integrity: sha512-cflHtb0+E4HCm9nIeCGOn4TMAc9R+f2uhCwzZOV6ZMHIwbuVjt/L+3tBo3NULhKWLDSsklRdaU2qV/5elau3wg==} + engines: {node: '>=18.0.0'} + cpu: [arm64, x64] + os: [win32] + + '@node-llama-cpp/win-x64-cuda@3.1.1': + resolution: {integrity: sha512-OHk53PpJ6zfJwCUKCS/A+zFEh8JxguuYFnqqyteZoNdI9h3ggOk9QLrn1RQ1LH232Rvfu7AoqGiVgFSB8Jkz4Q==} + engines: {node: '>=18.0.0'} + cpu: [x64] + os: [win32] + + '@node-llama-cpp/win-x64-vulkan@3.1.1': + resolution: {integrity: sha512-IuKmcN1LUDiQfQAGkTVdAF4J55VzC87PYjYYQNthfojFxwG8GFxK/VnngmmGXybGd6pwK8Cvymun2bNJVQKVoA==} + engines: {node: '>=18.0.0'} + cpu: [x64] + os: [win32] + + '@node-llama-cpp/win-x64@3.1.1': + resolution: {integrity: sha512-/hK4+wyOe7Q3+UlM/eSmm2GkrS7FwXp+IXAo+id/PobOYEn7l5r1ntqaTgwh3xWefezD3UDSCH1OqkZ2EsVdig==} + engines: {node: '>=18.0.0'} + cpu: [x64] + os: [win32] + '@nodelib/fs.scandir@2.1.5': resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} engines: {node: '>= 8'} @@ -573,10 +652,169 @@ packages: engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} deprecated: This functionality has been moved to @npmcli/fs + '@octokit/app@15.1.0': + resolution: {integrity: sha512-TkBr7QgOmE6ORxvIAhDbZsqPkF7RSqTY4pLTtUQCvr6dTXqvi2fFo46q3h1lxlk/sGMQjqyZ0kEahkD/NyzOHg==} + engines: {node: '>= 18'} + + '@octokit/auth-app@7.1.1': + resolution: {integrity: sha512-kRAd6yelV9OgvlEJE88H0VLlQdZcag9UlLr7dV0YYP37X8PPDvhgiTy66QVhDXdyoT0AleFN2w/qXkPdrSzINg==} + engines: {node: '>= 18'} + + '@octokit/auth-oauth-app@8.1.1': + resolution: {integrity: sha512-5UtmxXAvU2wfcHIPPDWzVSAWXVJzG3NWsxb7zCFplCWEmMCArSZV0UQu5jw5goLQXbFyOr5onzEH37UJB3zQQg==} + engines: {node: '>= 18'} + + '@octokit/auth-oauth-device@7.1.1': + resolution: {integrity: sha512-HWl8lYueHonuyjrKKIup/1tiy0xcmQCdq5ikvMO1YwkNNkxb6DXfrPjrMYItNLyCP/o2H87WuijuE+SlBTT8eg==} + engines: {node: '>= 18'} + + '@octokit/auth-oauth-user@5.1.1': + resolution: {integrity: sha512-rRkMz0ErOppdvEfnemHJXgZ9vTPhBuC6yASeFaB7I2yLMd7QpjfrL1mnvRPlyKo+M6eeLxrKanXJ9Qte29SRsw==} + engines: {node: '>= 18'} + + '@octokit/auth-token@5.1.1': + resolution: {integrity: sha512-rh3G3wDO8J9wSjfI436JUKzHIxq8NaiL0tVeB2aXmG6p/9859aUOAjA9pmSPNGGZxfwmaJ9ozOJImuNVJdpvbA==} + engines: {node: '>= 18'} + + '@octokit/auth-unauthenticated@6.1.0': + resolution: {integrity: sha512-zPSmfrUAcspZH/lOFQnVnvjQZsIvmfApQH6GzJrkIunDooU1Su2qt2FfMTSVPRp7WLTQyC20Kd55lF+mIYaohQ==} + engines: {node: '>= 18'} + + '@octokit/core@6.1.2': + resolution: {integrity: sha512-hEb7Ma4cGJGEUNOAVmyfdB/3WirWMg5hDuNFVejGEDFqupeOysLc2sG6HJxY2etBp5YQu5Wtxwi020jS9xlUwg==} + engines: {node: '>= 18'} + + '@octokit/endpoint@10.1.1': + resolution: {integrity: sha512-JYjh5rMOwXMJyUpj028cu0Gbp7qe/ihxfJMLc8VZBMMqSwLgOxDI1911gV4Enl1QSavAQNJcwmwBF9M0VvLh6Q==} + engines: {node: '>= 18'} + + '@octokit/graphql@8.1.1': + resolution: {integrity: sha512-ukiRmuHTi6ebQx/HFRCXKbDlOh/7xEV6QUXaE7MJEKGNAncGI/STSbOkl12qVXZrfZdpXctx5O9X1AIaebiDBg==} + engines: {node: '>= 18'} + + '@octokit/oauth-app@7.1.3': + resolution: {integrity: sha512-EHXbOpBkSGVVGF1W+NLMmsnSsJRkcrnVmDKt0TQYRBb6xWfWzoi9sBD4DIqZ8jGhOWO/V8t4fqFyJ4vDQDn9bg==} + engines: {node: '>= 18'} + + '@octokit/oauth-authorization-url@7.1.1': + resolution: {integrity: sha512-ooXV8GBSabSWyhLUowlMIVd9l1s2nsOGQdlP2SQ4LnkEsGXzeCvbSbCPdZThXhEFzleGPwbapT0Sb+YhXRyjCA==} + engines: {node: '>= 18'} + + '@octokit/oauth-methods@5.1.2': + resolution: {integrity: sha512-C5lglRD+sBlbrhCUTxgJAFjWgJlmTx5bQ7Ch0+2uqRjYv7Cfb5xpX4WuSC9UgQna3sqRGBL9EImX9PvTpMaQ7g==} + engines: {node: '>= 18'} + + '@octokit/openapi-types@22.2.0': + resolution: {integrity: sha512-QBhVjcUa9W7Wwhm6DBFu6ZZ+1/t/oYxqc2tp81Pi41YNuJinbFRx8B133qVOrAaBbF7D/m0Et6f9/pZt9Rc+tg==} + + '@octokit/openapi-webhooks-types@8.3.0': + resolution: {integrity: sha512-vKLsoR4xQxg4Z+6rU/F65ItTUz/EXbD+j/d4mlq2GW8TsA4Tc8Kdma2JTAAJ5hrKWUQzkR/Esn2fjsqiVRYaQg==} + + '@octokit/plugin-paginate-graphql@5.2.3': + resolution: {integrity: sha512-EzFueuXVU3VHv5FwEXbdznn9EmyF0vA5LGDX6a8fJ9YJAlDgdYHRKJMO4Ghl2PPPJBxIPMDUJMnlUHqcvP7AnQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-paginate-rest@11.3.5': + resolution: {integrity: sha512-cgwIRtKrpwhLoBi0CUNuY83DPGRMaWVjqVI/bGKsLJ4PzyWZNaEmhHroI2xlrVXkk6nFv0IsZpOp+ZWSWUS2AQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-rest-endpoint-methods@13.2.6': + resolution: {integrity: sha512-wMsdyHMjSfKjGINkdGKki06VEkgdEldIGstIEyGX0wbYHGByOwN/KiM+hAAlUwAtPkP3gvXtVQA9L3ITdV2tVw==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-retry@7.1.2': + resolution: {integrity: sha512-XOWnPpH2kJ5VTwozsxGurw+svB2e61aWlmk5EVIYZPwFK5F9h4cyPyj9CIKRyMXMHSwpIsI3mPOdpMmrRhe7UQ==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': '>=6' + + '@octokit/plugin-throttling@9.3.2': + resolution: {integrity: sha512-FqpvcTpIWFpMMwIeSoypoJXysSAQ3R+ALJhXXSG1HTP3YZOIeLmcNcimKaXxTcws+Sh6yoRl13SJ5r8sXc1Fhw==} + engines: {node: '>= 18'} + peerDependencies: + '@octokit/core': ^6.0.0 + + '@octokit/request-error@6.1.5': + resolution: {integrity: sha512-IlBTfGX8Yn/oFPMwSfvugfncK2EwRLjzbrpifNaMY8o/HTEAFqCA1FZxjD9cWvSKBHgrIhc4CSBIzMxiLsbzFQ==} + engines: {node: '>= 18'} + + '@octokit/request@9.1.3': + resolution: {integrity: sha512-V+TFhu5fdF3K58rs1pGUJIDH5RZLbZm5BI+MNF+6o/ssFNT4vWlCh/tVpF3NxGtP15HUxTTMUbsG5llAuU2CZA==} + engines: {node: '>= 18'} + + '@octokit/types@13.6.1': + resolution: {integrity: sha512-PHZE9Z+kWXb23Ndik8MKPirBPziOc0D2/3KH1P+6jK5nGWe96kadZuE4jev2/Jq7FvIfTlT2Ltg8Fv2x1v0a5g==} + + '@octokit/webhooks-methods@5.1.0': + resolution: {integrity: sha512-yFZa3UH11VIxYnnoOYCVoJ3q4ChuSOk2IVBBQ0O3xtKX4x9bmKb/1t+Mxixv2iUhzMdOl1qeWJqEhouXXzB3rQ==} + engines: {node: '>= 18'} + + '@octokit/webhooks@13.3.0': + resolution: {integrity: sha512-TUkJLtI163Bz5+JK0O+zDkQpn4gKwN+BovclUvCj6pI/6RXrFqQvUMRS2M+Rt8Rv0qR3wjoMoOPmpJKeOh0nBg==} + engines: {node: '>= 18'} + '@pkgjs/parseargs@0.11.0': resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@reflink/reflink-darwin-arm64@0.1.16': + resolution: {integrity: sha512-s61AeZ0br2LtqOl2Rbq0k833hQ00sXJ+l9LGJmjM53dupWft3HEX9C5WUIMDDiU2Scx7f7UKAE4DvIvv7XjBWQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@reflink/reflink-darwin-x64@0.1.16': + resolution: {integrity: sha512-ssrJj3K0Euua2LAkA4ff5y693wGKUHfznrGeWWtMw2aoLZRAH+C9Ne5oQvmcPPEK6wa929nRhA0ABrvhUa9mvA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@reflink/reflink-linux-arm64-gnu@0.1.16': + resolution: {integrity: sha512-I4PCAcsAKFRSfOSHdz+rck6ARg4jzo4PvVqcnS2odcXy1Inbehxk3IcKBpHnuuDbXRCUoWV6NP7wSx1wG7ZBuA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@reflink/reflink-linux-arm64-musl@0.1.16': + resolution: {integrity: sha512-xzcdtfwTXWUzN5yHdJgCdyAZSBO0faSgTqGdT4QKDxGHmiokf7+tgVBd6bU2nT4sL26AiIFyIBwp8buXGQYyaw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + + '@reflink/reflink-linux-x64-gnu@0.1.16': + resolution: {integrity: sha512-4/jscn1A/hx6maOowUjcvIs7YBs0fj//1vxB16TdMYk3tH9FHNmMBv5Pvw8eeRDimAzHP9fQJ9/t4dR6HCf32w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@reflink/reflink-linux-x64-musl@0.1.16': + resolution: {integrity: sha512-03kRXoAXhS/ZKxU2TKax59mLyKP7mev0EoIs+yXejUQo6D4uU46j+Sc243xMp72jRTgbWV4hQykcov98KtXEKQ==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + + '@reflink/reflink-win32-arm64-msvc@0.1.16': + resolution: {integrity: sha512-N7r+6YB3vXijs7PF3eg306B5s82hGS2TzsMM4+B9DNN9sbvN2yV5HQw29zyCXHY9c9SLe5kEzERp0rsDtN+6TA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@reflink/reflink-win32-x64-msvc@0.1.16': + resolution: {integrity: sha512-CaslGjfhpvtjHqr8Cw1MhkYZAkcLWFiL1pMXOPv4fwngtLC5/OlcL/Y4Rw2QEZwDvPG3gaeY7pjF1NYEGnDrZA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@reflink/reflink@0.1.16': + resolution: {integrity: sha512-i2zYt2FH1CE/1HUwK96HcwiahGhaS4wSCgaUnlIrl/4bxTnaZ0T/sYcLJ5VNSrbuczWjtyJ4WUROB+qMcRI9jA==} + engines: {node: '>= 10'} + '@remix-run/router@1.19.1': resolution: {integrity: sha512-S45oynt/WH19bHbIXjtli6QmwNYvaz+vtnubvNpNDvUOoA/OWh6j1OikIP3G+v5GHdxyC6EXoChG3HgYGEUfcg==} engines: {node: '>=14.0.0'} @@ -852,10 +1090,17 @@ packages: resolution: {integrity: sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==} engines: {node: '>=10'} + '@tinyhttp/content-disposition@2.2.2': + resolution: {integrity: sha512-crXw1txzrS36huQOyQGYFvhTeLeG0Si1xu+/l6kXUVYpE0TjFjEZRqTbuadQLfKGZ0jaI+jJoRyqaWwxOSHW2g==} + engines: {node: '>=12.20.0'} + '@tootallnate/once@2.0.0': resolution: {integrity: sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==} engines: {node: '>= 10'} + '@types/aws-lambda@8.10.145': + resolution: {integrity: sha512-dtByW6WiFk5W5Jfgz1VM+YPA21xMXTuSFoLYIDY0L44jDLLflVPtZkYuu3/YxpGcvjzKFBZLU+GyKjR0HOYtyw==} + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -999,6 +1244,10 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} + ansi-escapes@6.2.1: + resolution: {integrity: sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==} + engines: {node: '>=14.16'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1092,6 +1341,9 @@ packages: resolution: {integrity: sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==} engines: {node: '>=0.12.0'} + async-retry@1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} @@ -1106,6 +1358,9 @@ packages: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} engines: {node: '>= 0.4'} + axios@1.7.7: + resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==} + bail@2.0.2: resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} @@ -1115,6 +1370,9 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + before-after-hook@3.0.2: + resolution: {integrity: sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==} + bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -1127,6 +1385,9 @@ packages: boolean@3.2.0: resolution: {integrity: sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==} + bottleneck@2.19.5: + resolution: {integrity: sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==} + bowser@2.11.0: resolution: {integrity: sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==} @@ -1157,6 +1418,10 @@ packages: builder-util@25.0.3: resolution: {integrity: sha512-eH5c1ukdY2xjtFQWQ6jlzEuXuqcuAVc3UQ6V6fdYu9Kg3CkDbCR82Mox42uaJDmee9WXSbP/88cOworFdOHPhw==} + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + cacache@16.1.3: resolution: {integrity: sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==} engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} @@ -1191,6 +1456,10 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + chalk@5.3.0: + resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==} + engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + character-entities-html4@2.1.0: resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} @@ -1203,6 +1472,9 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} + chmodrp@1.0.2: + resolution: {integrity: sha512-TdngOlFV1FLTzU0o1w8MB6/BFywhtLC0SzRTGJU7T9lmdjlCWeMRt1iVo0Ki+ldwNk0BqNiKoc8xpLZEQ8mY1w==} + chownr@2.0.0: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} @@ -1214,6 +1486,10 @@ packages: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} engines: {node: '>=8'} + ci-info@4.0.0: + resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==} + engines: {node: '>=8'} + clean-stack@2.2.0: resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} engines: {node: '>=6'} @@ -1222,6 +1498,10 @@ packages: resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} engines: {node: '>=8'} + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + cli-spinners@2.9.2: resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==} engines: {node: '>=6'} @@ -1241,6 +1521,11 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} + cmake-js@7.3.0: + resolution: {integrity: sha512-dXs2zq9WxrV87bpJ+WbnGKv8WUBXDw8blNiwNHoRe/it+ptscxhQHKB1SJXa1w+kocLMeP28Tk4/eTCezg4o+w==} + engines: {node: '>= 14.15.0'} + hasBin: true + color-convert@1.9.3: resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} @@ -1265,6 +1550,10 @@ packages: comma-separated-tokens@2.0.3: resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + commander@2.20.3: resolution: {integrity: sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==} @@ -1310,6 +1599,11 @@ packages: crc@3.8.0: resolution: {integrity: sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==} + cross-env@7.0.3: + resolution: {integrity: sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==} + engines: {node: '>=10.14', npm: '>=6', yarn: '>=1'} + hasBin: true + cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1345,6 +1639,10 @@ packages: resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==} engines: {node: '>=10'} + deep-extend@0.6.0: + resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==} + engines: {node: '>=4.0.0'} + deep-is@0.1.4: resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} @@ -1435,6 +1733,9 @@ packages: engines: {node: '>= 12.20.55'} hasBin: true + emoji-regex@10.4.0: + resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -1451,6 +1752,10 @@ packages: resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} engines: {node: '>=6'} + env-var@7.5.0: + resolution: {integrity: sha512-mKZOzLRN0ETzau2W2QXefbFjo5EF4yWq28OyKb9ICdeNhHJlOE/pHHnz4hdYJ9cNZXcJHo5xN4OT4pzuSHSNvA==} + engines: {node: '>=10'} + err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} @@ -1571,6 +1876,9 @@ packages: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} + eventemitter3@5.0.1: + resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + exponential-backoff@3.1.1: resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} @@ -1612,6 +1920,14 @@ packages: filelist@1.0.4: resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} + filename-reserved-regex@3.0.0: + resolution: {integrity: sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + filenamify@6.0.0: + resolution: {integrity: sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==} + engines: {node: '>=16'} + find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} @@ -1623,6 +1939,15 @@ packages: flatted@3.3.1: resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==} + follow-redirects@1.15.9: + resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} + engines: {node: '>=4.0'} + peerDependencies: + debug: '*' + peerDependenciesMeta: + debug: + optional: true + for-each@0.3.3: resolution: {integrity: sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==} @@ -1695,6 +2020,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.2.0: + resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==} + engines: {node: '>=18'} + get-intrinsic@1.2.4: resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==} engines: {node: '>= 0.4'} @@ -1856,6 +2185,9 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + ini@1.3.8: + resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} + inline-style-parser@0.2.3: resolution: {integrity: sha512-qlD8YNDqyTKTyuITrDOffsl6Tdhv+UC4hcdAVuQsK4IMQ99nSgd1MIA/Q+jQYoh9r3hVUXhYh7urSRmXPkW04g==} @@ -1867,6 +2199,11 @@ packages: resolution: {integrity: sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==} engines: {node: '>= 12'} + ipull@3.9.0: + resolution: {integrity: sha512-s/gZfxkfZKFJxojocTQwqWqtAxVzHKQZ0ivWvIAih3JpPN5mXkIOWzVm4/XKUmQELxan52REe3epRP69gfVQXg==} + engines: {node: '>=18.0.0'} + hasBin: true + is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} @@ -1922,6 +2259,10 @@ packages: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-fullwidth-code-point@5.0.0: + resolution: {integrity: sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==} + engines: {node: '>=18'} + is-generator-function@1.0.10: resolution: {integrity: sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==} engines: {node: '>= 0.4'} @@ -1937,6 +2278,10 @@ packages: resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} engines: {node: '>=8'} + is-interactive@2.0.0: + resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==} + engines: {node: '>=12'} + is-lambda@1.0.1: resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} @@ -1988,6 +2333,14 @@ packages: resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} engines: {node: '>=10'} + is-unicode-supported@1.3.0: + resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} + engines: {node: '>=12'} + + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + is-weakmap@2.0.2: resolution: {integrity: sha512-K5pXYOm9wqY1RgjpL3YTkF39tni1XajUIkawTLUo9EZEVUFga5gSQJF8nNS7ZwJQ02y+1YCNYcMh+HIf1ZqE+w==} engines: {node: '>= 0.4'} @@ -2016,6 +2369,10 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + isexe@3.1.1: + resolution: {integrity: sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==} + engines: {node: '>=16'} + iterator.prototype@1.1.2: resolution: {integrity: sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w==} @@ -2087,10 +2444,16 @@ packages: resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} engines: {node: '>= 0.8.0'} + lifecycle-utils@1.7.0: + resolution: {integrity: sha512-suNHxB8zsWrvsWxsmy9PsOcHuThRsCzvUhtGwxfvYAl8mbeWv7lt+wNT3q9KgILWmNe9zEVZ6PXo1gsvpYIdvw==} + locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} engines: {node: '>=10'} + lodash.debounce@4.0.8: + resolution: {integrity: sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==} + lodash.defaults@4.2.0: resolution: {integrity: sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==} @@ -2116,6 +2479,14 @@ packages: resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} engines: {node: '>=10'} + log-symbols@6.0.0: + resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==} + engines: {node: '>=18'} + + log-symbols@7.0.0: + resolution: {integrity: sha512-zrc91EDk2M+2AXo/9BTvK91pqb7qrPg2nX/Hy+u8a5qQlbaOflCKO+6SqgZ+M+xUFxGdKTgwnGiL96b1W3ikRA==} + engines: {node: '>=18'} + longest-streak@3.1.0: resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==} @@ -2123,6 +2494,10 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lowdb@7.0.1: + resolution: {integrity: sha512-neJAj8GwF0e8EpycYIDFqEPcx9Qz4GUho20jWFR7YiFeXzF1YMLdxB36PypcTSPMA+4+LvgyMacYhlr18Zlymw==} + engines: {node: '>=18'} + lowercase-keys@2.0.0: resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==} engines: {node: '>=8'} @@ -2173,6 +2548,9 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + memory-stream@1.0.0: + resolution: {integrity: sha512-Wm13VcsPIMdG96dzILfij09PvuS3APtcKNh7M28FsCA/w6+1mjR7hhPmfFNoilX9xU7wTdhsH5lJAm6XNzdtww==} + micromark-core-commonmark@2.0.1: resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==} @@ -2253,6 +2631,10 @@ packages: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + mimic-response@1.0.1: resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==} engines: {node: '>=4'} @@ -2328,6 +2710,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@5.0.7: + resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==} + engines: {node: ^18 || >=20} + hasBin: true + natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -2342,6 +2729,13 @@ packages: node-addon-api@1.7.2: resolution: {integrity: sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==} + node-addon-api@8.1.0: + resolution: {integrity: sha512-yBY+qqWSv3dWKGODD6OGE6GnTX7Q2r+4+DfpqxHSHh8x0B4EKP9+wVGLS6U/AM1vxSNNmUEuIV5EGhYwPpfOwQ==} + engines: {node: ^18 || ^20 || >= 21} + + node-api-headers@1.3.0: + resolution: {integrity: sha512-8Bviwtw4jNhv0B2qDjj4M5e6GyAuGtxsmZTrFJu3S3Z0+oHwIgSUdIKkKJmZd+EbMo7g3v4PLBbrjxwmZOqMBg==} + node-api-version@0.2.0: resolution: {integrity: sha512-fthTTsi8CxaBXMaBAD7ST2uylwvsnYxh2PfaScwpMhos6KlSFajXQPcM4ogNE1q2s3Lbz9GCGqeIHC+C6OZnKg==} @@ -2363,6 +2757,16 @@ packages: engines: {node: ^12.13 || ^14.13 || >=16} hasBin: true + node-llama-cpp@3.1.1: + resolution: {integrity: sha512-CyXwxlJiAAELhy265wndAwV+nrUvVJk7+BjiYtz8BAUXCPpzZTeZTNnmcDO21FTutQyRuWhiNA/yzOLeDvmuAQ==} + engines: {node: '>=18.0.0'} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + peerDependenciesMeta: + typescript: + optional: true + node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} @@ -2412,6 +2816,10 @@ packages: resolution: {integrity: sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==} engines: {node: '>= 0.4'} + octokit@4.0.2: + resolution: {integrity: sha512-wbqF4uc1YbcldtiBFfkSnquHtECEIpYD78YUXI6ri1Im5OO2NLo6ZVpRdbJpdnpZ05zMrVPssNiEo6JQtea+Qg==} + engines: {node: '>= 18'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2419,6 +2827,10 @@ packages: resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} engines: {node: '>=6'} + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + openai@4.61.0: resolution: {integrity: sha512-xkygRBRLIUumxzKGb1ug05pWmJROQsHkGuj/N6Jiw2dj0dI19JvbFpErSZKmJ/DA+0IvpcugZqCAyk8iLpyM6Q==} hasBin: true @@ -2436,6 +2848,10 @@ packages: resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} engines: {node: '>=10'} + ora@8.1.0: + resolution: {integrity: sha512-GQEkNkH/GHOhPFXcqZs3IDahXEQcQxsSjEkK4KvEEST4t7eNzoMjxTzef+EZ+JluDEV+Raoi3WQ2CflnRdSVnQ==} + engines: {node: '>=18'} + p-cancelable@2.1.1: resolution: {integrity: sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==} engines: {node: '>=8'} @@ -2462,6 +2878,14 @@ packages: parse-entities@4.0.1: resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==} + parse-ms@3.0.0: + resolution: {integrity: sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==} + engines: {node: '>=12'} + + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2507,6 +2931,18 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + pretty-bytes@6.1.1: + resolution: {integrity: sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==} + engines: {node: ^14.13.1 || >=16.0.0} + + pretty-ms@8.0.0: + resolution: {integrity: sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==} + engines: {node: '>=14.16'} + + pretty-ms@9.1.0: + resolution: {integrity: sha512-o1piW0n3tgKIKCwk2vpM/vOV13zjJzvP37Ioze54YlTHE06m4tjEbzg9WsKkvTuyYln2DHjo5pY4qrZGI0otpw==} + engines: {node: '>=18'} + process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} @@ -2529,9 +2965,15 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} + proper-lockfile@4.1.2: + resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} + property-information@6.5.0: resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==} + proxy-from-env@1.1.0: + resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} + pump@3.0.0: resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} @@ -2550,6 +2992,10 @@ packages: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} + rc@1.2.8: + resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} + hasBin: true + react-bootstrap-icons@1.11.4: resolution: {integrity: sha512-lnkOpNEZ/Zr7mNxvjA9efuarCPSgtOuGA55XiRj7ASJnBjb1wEAdtJOd2Aiv9t07r7FLI1IgyZPg9P6jqWD/IA==} peerDependencies: @@ -2648,10 +3094,18 @@ packages: resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} engines: {node: '>=8'} + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + retry@0.12.0: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + reusify@1.0.4: resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2745,14 +3199,24 @@ packages: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} + simple-git@3.27.0: + resolution: {integrity: sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==} + simple-update-notifier@2.0.0: resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==} engines: {node: '>=10'} + sleep-promise@9.1.0: + resolution: {integrity: sha512-UHYzVpz9Xn8b+jikYSD6bqvf754xL2uBUzDFwiU6NcdZeifPr6UfgU43xpkPu67VMS88+TI2PSI7Eohgqf2fKA==} + slice-ansi@3.0.0: resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} engines: {node: '>=8'} + slice-ansi@7.1.0: + resolution: {integrity: sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==} + engines: {node: '>=18'} + smart-buffer@4.2.0: resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} @@ -2790,6 +3254,18 @@ packages: resolution: {integrity: sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==} engines: {node: '>= 6'} + stdin-discarder@0.2.2: + resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==} + engines: {node: '>=18'} + + stdout-update@4.0.1: + resolution: {integrity: sha512-wiS21Jthlvl1to+oorePvcyrIkiG/6M3D3VTmDUlJm7Cy6SbFhKkAvX+YBuHLxck/tO3mrdpC/cNesigQc3+UQ==} + engines: {node: '>=16.0.0'} + + steno@4.0.2: + resolution: {integrity: sha512-yhPIQXjrlt1xv7dyPQg2P17URmXbuM5pdGkpiMB3RenprfiBlvK415Lctfe0eshk90oA7/tNq7WEiMK8RSP39A==} + engines: {node: '>=18'} + string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2798,6 +3274,10 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + string.prototype.matchall@4.0.11: resolution: {integrity: sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==} engines: {node: '>= 0.4'} @@ -2833,6 +3313,10 @@ packages: resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} engines: {node: '>=12'} + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -2968,6 +3452,12 @@ packages: unist-util-visit@5.0.0: resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==} + universal-github-app-jwt@2.2.0: + resolution: {integrity: sha512-G5o6f95b5BggDGuUfKDApKaCgNYy2x7OdHY0zSMF081O0EJobw+1130VONhrA7ezGSV2FNOGyM+KQpQZAr9bIQ==} + + universal-user-agent@7.0.2: + resolution: {integrity: sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -2985,6 +3475,9 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} + url-join@4.0.1: + resolution: {integrity: sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==} + utf8-byte-length@1.0.5: resolution: {integrity: sha512-Xn0w3MtiQ6zoz2vFyUVruaCL53O/DwUvkEeOvj+uulMm0BkUGYWmBYVyElqZaSLhY6ZD0ulfU3aBra2aVT4xfA==} @@ -2995,6 +3488,10 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true + validate-npm-package-name@5.0.1: + resolution: {integrity: sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==} + engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} + verror@1.10.1: resolution: {integrity: sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==} engines: {node: '>=0.6.0'} @@ -3069,6 +3566,11 @@ packages: engines: {node: '>= 8'} hasBin: true + which@4.0.0: + resolution: {integrity: sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==} + engines: {node: ^16.13.0 || >=18.0.0} + hasBin: true + wide-align@1.1.5: resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} @@ -3116,6 +3618,10 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yoctocolors@2.1.1: + resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + engines: {node: '>=18'} + zip-stream@4.1.1: resolution: {integrity: sha512-9qv4rlDiopXg4E69k+vMHjNN63YFMe9sZMrdlvKnCjlCRWeCBswPPMPUfx+ipsAWq1LXHe70RcbaHdJJpS6hyQ==} engines: {node: '>= 10'} @@ -3910,6 +4416,8 @@ snapshots: '@huggingface/jinja@0.3.0': {} + '@huggingface/jinja@0.3.1': {} + '@humanwhocodes/module-importer@1.0.1': {} '@humanwhocodes/retry@0.3.0': {} @@ -3946,6 +4454,14 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 + '@kwsites/file-exists@1.1.1': + dependencies: + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + + '@kwsites/promise-deferred@1.1.1': {} + '@malept/cross-spawn-promise@2.0.0': dependencies: cross-spawn: 7.0.3 @@ -3959,6 +4475,39 @@ snapshots: transitivePeerDependencies: - supports-color + '@node-llama-cpp/linux-arm64@3.1.1': + optional: true + + '@node-llama-cpp/linux-armv7l@3.1.1': + optional: true + + '@node-llama-cpp/linux-x64-cuda@3.1.1': + optional: true + + '@node-llama-cpp/linux-x64-vulkan@3.1.1': + optional: true + + '@node-llama-cpp/linux-x64@3.1.1': + optional: true + + '@node-llama-cpp/mac-arm64-metal@3.1.1': + optional: true + + '@node-llama-cpp/mac-x64@3.1.1': + optional: true + + '@node-llama-cpp/win-arm64@3.1.1': + optional: true + + '@node-llama-cpp/win-x64-cuda@3.1.1': + optional: true + + '@node-llama-cpp/win-x64-vulkan@3.1.1': + optional: true + + '@node-llama-cpp/win-x64@3.1.1': + optional: true + '@nodelib/fs.scandir@2.1.5': dependencies: '@nodelib/fs.stat': 2.0.5 @@ -3981,9 +4530,191 @@ snapshots: mkdirp: 1.0.4 rimraf: 3.0.2 + '@octokit/app@15.1.0': + dependencies: + '@octokit/auth-app': 7.1.1 + '@octokit/auth-unauthenticated': 6.1.0 + '@octokit/core': 6.1.2 + '@octokit/oauth-app': 7.1.3 + '@octokit/plugin-paginate-rest': 11.3.5(@octokit/core@6.1.2) + '@octokit/types': 13.6.1 + '@octokit/webhooks': 13.3.0 + + '@octokit/auth-app@7.1.1': + dependencies: + '@octokit/auth-oauth-app': 8.1.1 + '@octokit/auth-oauth-user': 5.1.1 + '@octokit/request': 9.1.3 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + lru-cache: 10.4.3 + universal-github-app-jwt: 2.2.0 + universal-user-agent: 7.0.2 + + '@octokit/auth-oauth-app@8.1.1': + dependencies: + '@octokit/auth-oauth-device': 7.1.1 + '@octokit/auth-oauth-user': 5.1.1 + '@octokit/request': 9.1.3 + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/auth-oauth-device@7.1.1': + dependencies: + '@octokit/oauth-methods': 5.1.2 + '@octokit/request': 9.1.3 + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/auth-oauth-user@5.1.1': + dependencies: + '@octokit/auth-oauth-device': 7.1.1 + '@octokit/oauth-methods': 5.1.2 + '@octokit/request': 9.1.3 + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/auth-token@5.1.1': {} + + '@octokit/auth-unauthenticated@6.1.0': + dependencies: + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + + '@octokit/core@6.1.2': + dependencies: + '@octokit/auth-token': 5.1.1 + '@octokit/graphql': 8.1.1 + '@octokit/request': 9.1.3 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + before-after-hook: 3.0.2 + universal-user-agent: 7.0.2 + + '@octokit/endpoint@10.1.1': + dependencies: + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/graphql@8.1.1': + dependencies: + '@octokit/request': 9.1.3 + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/oauth-app@7.1.3': + dependencies: + '@octokit/auth-oauth-app': 8.1.1 + '@octokit/auth-oauth-user': 5.1.1 + '@octokit/auth-unauthenticated': 6.1.0 + '@octokit/core': 6.1.2 + '@octokit/oauth-authorization-url': 7.1.1 + '@octokit/oauth-methods': 5.1.2 + '@types/aws-lambda': 8.10.145 + universal-user-agent: 7.0.2 + + '@octokit/oauth-authorization-url@7.1.1': {} + + '@octokit/oauth-methods@5.1.2': + dependencies: + '@octokit/oauth-authorization-url': 7.1.1 + '@octokit/request': 9.1.3 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + + '@octokit/openapi-types@22.2.0': {} + + '@octokit/openapi-webhooks-types@8.3.0': {} + + '@octokit/plugin-paginate-graphql@5.2.3(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + + '@octokit/plugin-paginate-rest@11.3.5(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/types': 13.6.1 + + '@octokit/plugin-rest-endpoint-methods@13.2.6(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/types': 13.6.1 + + '@octokit/plugin-retry@7.1.2(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + bottleneck: 2.19.5 + + '@octokit/plugin-throttling@9.3.2(@octokit/core@6.1.2)': + dependencies: + '@octokit/core': 6.1.2 + '@octokit/types': 13.6.1 + bottleneck: 2.19.5 + + '@octokit/request-error@6.1.5': + dependencies: + '@octokit/types': 13.6.1 + + '@octokit/request@9.1.3': + dependencies: + '@octokit/endpoint': 10.1.1 + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + universal-user-agent: 7.0.2 + + '@octokit/types@13.6.1': + dependencies: + '@octokit/openapi-types': 22.2.0 + + '@octokit/webhooks-methods@5.1.0': {} + + '@octokit/webhooks@13.3.0': + dependencies: + '@octokit/openapi-webhooks-types': 8.3.0 + '@octokit/request-error': 6.1.5 + '@octokit/webhooks-methods': 5.1.0 + '@pkgjs/parseargs@0.11.0': optional: true + '@reflink/reflink-darwin-arm64@0.1.16': + optional: true + + '@reflink/reflink-darwin-x64@0.1.16': + optional: true + + '@reflink/reflink-linux-arm64-gnu@0.1.16': + optional: true + + '@reflink/reflink-linux-arm64-musl@0.1.16': + optional: true + + '@reflink/reflink-linux-x64-gnu@0.1.16': + optional: true + + '@reflink/reflink-linux-x64-musl@0.1.16': + optional: true + + '@reflink/reflink-win32-arm64-msvc@0.1.16': + optional: true + + '@reflink/reflink-win32-x64-msvc@0.1.16': + optional: true + + '@reflink/reflink@0.1.16': + optionalDependencies: + '@reflink/reflink-darwin-arm64': 0.1.16 + '@reflink/reflink-darwin-x64': 0.1.16 + '@reflink/reflink-linux-arm64-gnu': 0.1.16 + '@reflink/reflink-linux-arm64-musl': 0.1.16 + '@reflink/reflink-linux-x64-gnu': 0.1.16 + '@reflink/reflink-linux-x64-musl': 0.1.16 + '@reflink/reflink-win32-arm64-msvc': 0.1.16 + '@reflink/reflink-win32-x64-msvc': 0.1.16 + optional: true + '@remix-run/router@1.19.1': {} '@rollup/rollup-android-arm-eabi@4.21.2': @@ -4337,8 +5068,12 @@ snapshots: dependencies: defer-to-connect: 2.0.1 + '@tinyhttp/content-disposition@2.2.2': {} + '@tootallnate/once@2.0.0': {} + '@types/aws-lambda@8.10.145': {} + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.25.3 @@ -4511,6 +5246,8 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 + ansi-escapes@6.2.1: {} + ansi-regex@5.0.1: {} ansi-regex@6.1.0: {} @@ -4673,6 +5410,10 @@ snapshots: async-exit-hook@2.0.1: {} + async-retry@1.3.3: + dependencies: + retry: 0.13.1 + async@3.2.6: {} asynckit@0.4.0: {} @@ -4683,12 +5424,22 @@ snapshots: dependencies: possible-typed-array-names: 1.0.0 + axios@1.7.7(debug@4.3.6): + dependencies: + follow-redirects: 1.15.9(debug@4.3.6) + form-data: 4.0.0 + proxy-from-env: 1.1.0 + transitivePeerDependencies: + - debug + bail@2.0.2: {} balanced-match@1.0.2: {} base64-js@1.5.1: {} + before-after-hook@3.0.2: {} + bl@4.1.0: dependencies: buffer: 5.7.1 @@ -4704,6 +5455,8 @@ snapshots: boolean@3.2.0: optional: true + bottleneck@2.19.5: {} + bowser@2.11.0: {} brace-expansion@1.1.11: @@ -4759,6 +5512,8 @@ snapshots: transitivePeerDependencies: - supports-color + bytes@3.1.2: {} + cacache@16.1.3: dependencies: '@npmcli/fs': 2.1.2 @@ -4819,6 +5574,8 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 + chalk@5.3.0: {} + character-entities-html4@2.1.0: {} character-entities-legacy@3.0.0: {} @@ -4827,18 +5584,26 @@ snapshots: character-reference-invalid@2.0.1: {} + chmodrp@1.0.2: {} + chownr@2.0.0: {} chromium-pickle-js@0.2.0: {} ci-info@3.9.0: {} + ci-info@4.0.0: {} + clean-stack@2.2.0: {} cli-cursor@3.1.0: dependencies: restore-cursor: 3.1.0 + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + cli-spinners@2.9.2: {} cli-truncate@2.1.0: @@ -4859,6 +5624,24 @@ snapshots: clone@1.0.4: {} + cmake-js@7.3.0: + dependencies: + axios: 1.7.7(debug@4.3.6) + debug: 4.3.6 + fs-extra: 11.2.0 + lodash.isplainobject: 4.0.6 + memory-stream: 1.0.0 + node-api-headers: 1.3.0 + npmlog: 6.0.2 + rc: 1.2.8 + semver: 7.6.3 + tar: 6.2.1 + url-join: 4.0.1 + which: 2.0.2 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + color-convert@1.9.3: dependencies: color-name: 1.1.3 @@ -4879,6 +5662,8 @@ snapshots: comma-separated-tokens@2.0.3: {} + commander@10.0.1: {} + commander@2.20.3: optional: true @@ -4921,6 +5706,10 @@ snapshots: buffer: 5.7.1 optional: true + cross-env@7.0.3: + dependencies: + cross-spawn: 7.0.3 + cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -4959,6 +5748,8 @@ snapshots: dependencies: mimic-response: 3.1.0 + deep-extend@0.6.0: {} + deep-is@0.1.4: {} defaults@1.0.4: @@ -5093,6 +5884,8 @@ snapshots: transitivePeerDependencies: - supports-color + emoji-regex@10.4.0: {} + emoji-regex@8.0.0: {} emoji-regex@9.2.2: {} @@ -5108,6 +5901,8 @@ snapshots: env-paths@2.2.1: {} + env-var@7.5.0: {} + err-code@2.0.3: {} es-abstract@1.23.3: @@ -5339,6 +6134,8 @@ snapshots: event-target-shim@5.0.1: {} + eventemitter3@5.0.1: {} + exponential-backoff@3.1.1: {} extend@3.0.2: {} @@ -5382,6 +6179,12 @@ snapshots: dependencies: minimatch: 5.1.6 + filename-reserved-regex@3.0.0: {} + + filenamify@6.0.0: + dependencies: + filename-reserved-regex: 3.0.0 + find-up@5.0.0: dependencies: locate-path: 6.0.0 @@ -5394,6 +6197,10 @@ snapshots: flatted@3.3.1: {} + follow-redirects@1.15.9(debug@4.3.6): + optionalDependencies: + debug: 4.3.6 + for-each@0.3.3: dependencies: is-callable: 1.2.7 @@ -5478,6 +6285,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.2.0: {} + get-intrinsic@1.2.4: dependencies: es-errors: 1.3.0 @@ -5679,6 +6488,8 @@ snapshots: inherits@2.0.4: {} + ini@1.3.8: {} + inline-style-parser@0.2.3: {} internal-slot@1.0.7: @@ -5692,6 +6503,30 @@ snapshots: jsbn: 1.1.0 sprintf-js: 1.1.3 + ipull@3.9.0: + dependencies: + '@tinyhttp/content-disposition': 2.2.2 + async-retry: 1.3.3 + chalk: 5.3.0 + ci-info: 4.0.0 + cli-spinners: 2.9.2 + commander: 10.0.1 + eventemitter3: 5.0.1 + filenamify: 6.0.0 + fs-extra: 11.2.0 + is-unicode-supported: 2.1.0 + lifecycle-utils: 1.7.0 + lodash.debounce: 4.0.8 + lowdb: 7.0.1 + pretty-bytes: 6.1.1 + pretty-ms: 8.0.0 + sleep-promise: 9.1.0 + slice-ansi: 7.1.0 + stdout-update: 4.0.1 + strip-ansi: 7.1.0 + optionalDependencies: + '@reflink/reflink': 0.1.16 + is-alphabetical@2.0.1: {} is-alphanumerical@2.0.1: @@ -5745,6 +6580,10 @@ snapshots: is-fullwidth-code-point@3.0.0: {} + is-fullwidth-code-point@5.0.0: + dependencies: + get-east-asian-width: 1.2.0 + is-generator-function@1.0.10: dependencies: has-tostringtag: 1.0.2 @@ -5757,6 +6596,8 @@ snapshots: is-interactive@1.0.0: {} + is-interactive@2.0.0: {} + is-lambda@1.0.1: {} is-map@2.0.3: {} @@ -5796,6 +6637,10 @@ snapshots: is-unicode-supported@0.1.0: {} + is-unicode-supported@1.3.0: {} + + is-unicode-supported@2.1.0: {} + is-weakmap@2.0.2: {} is-weakref@1.0.2: @@ -5817,6 +6662,8 @@ snapshots: isexe@2.0.0: {} + isexe@3.1.1: {} + iterator.prototype@1.1.2: dependencies: define-properties: 1.2.1 @@ -5894,10 +6741,14 @@ snapshots: prelude-ls: 1.2.1 type-check: 0.4.0 + lifecycle-utils@1.7.0: {} + locate-path@6.0.0: dependencies: p-locate: 5.0.0 + lodash.debounce@4.0.8: {} + lodash.defaults@4.2.0: {} lodash.difference@4.5.0: {} @@ -5917,12 +6768,26 @@ snapshots: chalk: 4.1.2 is-unicode-supported: 0.1.0 + log-symbols@6.0.0: + dependencies: + chalk: 5.3.0 + is-unicode-supported: 1.3.0 + + log-symbols@7.0.0: + dependencies: + is-unicode-supported: 2.1.0 + yoctocolors: 2.1.1 + longest-streak@3.1.0: {} loose-envify@1.4.0: dependencies: js-tokens: 4.0.0 + lowdb@7.0.1: + dependencies: + steno: 4.0.2 + lowercase-keys@2.0.0: {} lru-cache@10.4.3: {} @@ -6052,6 +6917,10 @@ snapshots: dependencies: '@types/mdast': 4.0.4 + memory-stream@1.0.0: + dependencies: + readable-stream: 3.6.2 + micromark-core-commonmark@2.0.1: dependencies: decode-named-character-reference: 1.0.2 @@ -6195,6 +7064,8 @@ snapshots: mimic-fn@2.1.0: {} + mimic-function@5.0.1: {} + mimic-response@1.0.1: {} mimic-response@3.1.0: {} @@ -6260,6 +7131,8 @@ snapshots: nanoid@3.3.7: {} + nanoid@5.0.7: {} + natural-compare@1.4.0: {} negotiator@0.6.3: {} @@ -6271,6 +7144,10 @@ snapshots: node-addon-api@1.7.2: optional: true + node-addon-api@8.1.0: {} + + node-api-headers@1.3.0: {} + node-api-version@0.2.0: dependencies: semver: 7.6.3 @@ -6300,6 +7177,54 @@ snapshots: - bluebird - supports-color + node-llama-cpp@3.1.1(typescript@5.6.2): + dependencies: + '@huggingface/jinja': 0.3.1 + async-retry: 1.3.3 + bytes: 3.1.2 + chalk: 5.3.0 + chmodrp: 1.0.2 + cmake-js: 7.3.0 + cross-env: 7.0.3 + cross-spawn: 7.0.3 + env-var: 7.5.0 + filenamify: 6.0.0 + fs-extra: 11.2.0 + ignore: 5.3.2 + ipull: 3.9.0 + is-unicode-supported: 2.1.0 + lifecycle-utils: 1.7.0 + log-symbols: 7.0.0 + nanoid: 5.0.7 + node-addon-api: 8.1.0 + octokit: 4.0.2 + ora: 8.1.0 + pretty-ms: 9.1.0 + proper-lockfile: 4.1.2 + semver: 7.6.3 + simple-git: 3.27.0 + slice-ansi: 7.1.0 + stdout-update: 4.0.1 + strip-ansi: 7.1.0 + validate-npm-package-name: 5.0.1 + which: 4.0.0 + yargs: 17.7.2 + optionalDependencies: + '@node-llama-cpp/linux-arm64': 3.1.1 + '@node-llama-cpp/linux-armv7l': 3.1.1 + '@node-llama-cpp/linux-x64': 3.1.1 + '@node-llama-cpp/linux-x64-cuda': 3.1.1 + '@node-llama-cpp/linux-x64-vulkan': 3.1.1 + '@node-llama-cpp/mac-arm64-metal': 3.1.1 + '@node-llama-cpp/mac-x64': 3.1.1 + '@node-llama-cpp/win-arm64': 3.1.1 + '@node-llama-cpp/win-x64': 3.1.1 + '@node-llama-cpp/win-x64-cuda': 3.1.1 + '@node-llama-cpp/win-x64-vulkan': 3.1.1 + typescript: 5.6.2 + transitivePeerDependencies: + - supports-color + node-releases@2.0.18: {} nopt@6.0.0: @@ -6349,6 +7274,19 @@ snapshots: define-properties: 1.2.1 es-object-atoms: 1.0.0 + octokit@4.0.2: + dependencies: + '@octokit/app': 15.1.0 + '@octokit/core': 6.1.2 + '@octokit/oauth-app': 7.1.3 + '@octokit/plugin-paginate-graphql': 5.2.3(@octokit/core@6.1.2) + '@octokit/plugin-paginate-rest': 11.3.5(@octokit/core@6.1.2) + '@octokit/plugin-rest-endpoint-methods': 13.2.6(@octokit/core@6.1.2) + '@octokit/plugin-retry': 7.1.2(@octokit/core@6.1.2) + '@octokit/plugin-throttling': 9.3.2(@octokit/core@6.1.2) + '@octokit/request-error': 6.1.5 + '@octokit/types': 13.6.1 + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -6357,6 +7295,10 @@ snapshots: dependencies: mimic-fn: 2.1.0 + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + openai@4.61.0(encoding@0.1.13): dependencies: '@types/node': 18.19.50 @@ -6392,6 +7334,18 @@ snapshots: strip-ansi: 6.0.1 wcwidth: 1.0.1 + ora@8.1.0: + dependencies: + chalk: 5.3.0 + cli-cursor: 5.0.0 + cli-spinners: 2.9.2 + is-interactive: 2.0.0 + is-unicode-supported: 2.1.0 + log-symbols: 6.0.0 + stdin-discarder: 0.2.2 + string-width: 7.2.0 + strip-ansi: 7.1.0 + p-cancelable@2.1.1: {} p-limit@3.1.0: @@ -6423,6 +7377,10 @@ snapshots: is-decimal: 2.0.1 is-hexadecimal: 2.0.1 + parse-ms@3.0.0: {} + + parse-ms@4.0.0: {} + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} @@ -6458,6 +7416,16 @@ snapshots: prelude-ls@1.2.1: {} + pretty-bytes@6.1.1: {} + + pretty-ms@8.0.0: + dependencies: + parse-ms: 3.0.0 + + pretty-ms@9.1.0: + dependencies: + parse-ms: 4.0.0 + process-nextick-args@2.0.1: {} progress@2.0.3: {} @@ -6475,8 +7443,16 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 + proper-lockfile@4.1.2: + dependencies: + graceful-fs: 4.2.11 + retry: 0.12.0 + signal-exit: 3.0.7 + property-information@6.5.0: {} + proxy-from-env@1.1.0: {} + pump@3.0.0: dependencies: end-of-stream: 1.4.4 @@ -6492,6 +7468,13 @@ snapshots: quick-lru@5.1.1: {} + rc@1.2.8: + dependencies: + deep-extend: 0.6.0 + ini: 1.3.8 + minimist: 1.2.8 + strip-json-comments: 2.0.1 + react-bootstrap-icons@1.11.4(react@18.3.1): dependencies: prop-types: 15.8.1 @@ -6634,8 +7617,15 @@ snapshots: onetime: 5.1.2 signal-exit: 3.0.7 + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + retry@0.12.0: {} + retry@0.13.1: {} + reusify@1.0.4: {} rimraf@3.0.2: @@ -6754,10 +7744,20 @@ snapshots: signal-exit@4.1.0: {} + simple-git@3.27.0: + dependencies: + '@kwsites/file-exists': 1.1.1 + '@kwsites/promise-deferred': 1.1.1 + debug: 4.3.6 + transitivePeerDependencies: + - supports-color + simple-update-notifier@2.0.0: dependencies: semver: 7.6.3 + sleep-promise@9.1.0: {} + slice-ansi@3.0.0: dependencies: ansi-styles: 4.3.0 @@ -6765,6 +7765,11 @@ snapshots: is-fullwidth-code-point: 3.0.0 optional: true + slice-ansi@7.1.0: + dependencies: + ansi-styles: 6.2.1 + is-fullwidth-code-point: 5.0.0 + smart-buffer@4.2.0: {} socks-proxy-agent@7.0.0: @@ -6799,6 +7804,17 @@ snapshots: stat-mode@1.0.0: {} + stdin-discarder@0.2.2: {} + + stdout-update@4.0.1: + dependencies: + ansi-escapes: 6.2.1 + ansi-styles: 6.2.1 + string-width: 7.2.0 + strip-ansi: 7.1.0 + + steno@4.0.2: {} + string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -6811,6 +7827,12 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.1.0 + string-width@7.2.0: + dependencies: + emoji-regex: 10.4.0 + get-east-asian-width: 1.2.0 + strip-ansi: 7.1.0 + string.prototype.matchall@4.0.11: dependencies: call-bind: 1.0.7 @@ -6871,6 +7893,8 @@ snapshots: dependencies: ansi-regex: 6.1.0 + strip-json-comments@2.0.1: {} + strip-json-comments@3.1.1: {} strnum@1.0.5: {} @@ -7040,6 +8064,10 @@ snapshots: unist-util-is: 6.0.0 unist-util-visit-parents: 6.0.1 + universal-github-app-jwt@2.2.0: {} + + universal-user-agent@7.0.2: {} + universalify@0.1.2: {} universalify@2.0.1: {} @@ -7054,12 +8082,16 @@ snapshots: dependencies: punycode: 2.3.1 + url-join@4.0.1: {} + utf8-byte-length@1.0.5: {} util-deprecate@1.0.2: {} uuid@9.0.1: {} + validate-npm-package-name@5.0.1: {} + verror@1.10.1: dependencies: assert-plus: 1.0.0 @@ -7142,6 +8174,10 @@ snapshots: dependencies: isexe: 2.0.0 + which@4.0.0: + dependencies: + isexe: 3.1.1 + wide-align@1.1.5: dependencies: string-width: 4.2.3 @@ -7189,6 +8225,8 @@ snapshots: yocto-queue@0.1.0: {} + yoctocolors@2.1.1: {} + zip-stream@4.1.1: dependencies: archiver-utils: 3.0.4 diff --git a/preloader/index.js b/preloader/index.js new file mode 100644 index 0000000..b4d8885 --- /dev/null +++ b/preloader/index.js @@ -0,0 +1,14 @@ +const { contextBridge } = require('electron') +const { + loadModel, + chatCompletions, + abortCompletion, + setClient, + downloadModel, + updateModelSettings +} = require("./node-llama-cpp-preloader.js") + +contextBridge.exposeInMainWorld('node-llama-cpp', { + loadModel, chatCompletions, updateModelSettings, + abortCompletion, setClient, downloadModel +}) \ No newline at end of file diff --git a/preloader/node-llama-cpp-preloader.js b/preloader/node-llama-cpp-preloader.js new file mode 100644 index 0000000..e8e3466 --- /dev/null +++ b/preloader/node-llama-cpp-preloader.js @@ -0,0 +1,197 @@ +const { createWriteStream } = require("fs"); +const path = require("path"); + +let llama, getLlama, LlamaChatSession, current_model; + +async function importer() { + const nodeLlamaCpp = await import('node-llama-cpp') + getLlama = nodeLlamaCpp.getLlama; + LlamaChatSession = nodeLlamaCpp.LlamaChatSession; +} +importer(); + +const model_path = path.join(__dirname, '..', 'models') +// const model_path = path.join(path.dirname(fileURLToPath(import.meta.url)), '..', 'models') + +let llama_session, stop_signal; + +/** + * Load a model and init the llama session + * @param {String} model_name the model name to load, saved in /models folder + */ +async function loadModel(model_name = '') { + if(!model_name || current_model === model_name) return; + current_model = model_name; + + if(llama) await llama.dispose(); + + llama = await getLlama() + const model = await llama.loadModel({ + modelPath: path.join(model_path, model_name) + }) + + const context = await model.createContext(); + llama_session = new LlamaChatSession({ + contextSequence: context.getSequence() + }) +} + +/** + * Set the session, basically reset the history and return a static string 'fake-client' + * @param {String} client a fake client, everything using the same client and switch between clients just simply reset the chat history + * @returns {String} + */ +async function setClient(client, history = []) { + client; + llama_session.resetChatHistory(); + if(history.length) { + llama_session.setChatHistory(history.map(({role, content})=>{ + const is_assistant = role === 'assistant' + return { + type: is_assistant ? 'model' : role, + [is_assistant ? "response" : "text"]: is_assistant ? [content] : content + } + })) + } + + return 'fake-client'; +} + +/** + * extract message from given message object + * @param {any} message The latest user message, either string or any can be converted to string. If is array in the format of {content:String}, it will retrieve the last content + * @returns {String} the retrived message + */ +function findMessageText(message) { + if(typeof message === "string") return message; + else if(typeof message === "object") { + if(Array.isArray(message)) { + message = message.pop(); + if(typeof message === 'object' && message.content) { + return message.content; + } + } + } + return `${message}` +} + +let model_settings = {}; +function updateModelSettings(settings) { + model_settings = settings; +} + +/** + * @callback CallbackFunction + * @param {String} content The content to callback + * @param {Boolean} is_finished Whether the response has finished + */ + +/** + * Inference with LLM model, automatically continue on the history conversation, if want to reset conversation please call `clearHistory()` + * @param {String|any} latest_message The latest user message, either string or any can be converted to string. If is array in the format of {content:String}, it will retrieve the last content + * @param {Function?} cb Callback function + * @returns {Promise} the response text + */ +async function chatCompletions(latest_message, cb=null) { + if(!llama_session) await loadModel(); + latest_message = findMessageText(latest_message); + + const {max_tokens, top_p, temperature} = model_settings; + + stop_signal = new AbortController(); + const options = { + signal: stop_signal.signal, + stopOnAbortSignal: true, + maxTokens: max_tokens, + topP: top_p, + temperature + } + let resp_text = '' + if(cb) options.onTextChunk = chunk => { + resp_text += chunk; + cb(resp_text, false); + } + + const response = await llama_session.prompt(latest_message, options); + cb && cb(response, true); + stop_signal = null; + return response; +} + +/** + * Abort the completion + */ +function abortCompletion() { + stop_signal && stop_signal.abort(); +} + + +/** + * @callback DownloadProgressCallback + * @param {Number} progress The download progress in percentage + * @param {Boolean} is_finished Indicates whether the download is finished + */ + +/** + * @typedef ModelInfo + * @property {String} model_name name of model + * @property {String} url url of the model + * @property {Number?} size Size in bytes if the size information provided in Content-Length header, undefined otherwise + * @property {Number} finish_time Timestamp finished download + */ + +/** + * Downloads the given model to /models, if error with connection, resolves false, otherwise resolves true. + * @param {String} url URL of the model to be downloaded, model name would be the last part of url. + * @param {DownloadProgressCallback} cb callback function + * @returns {Promise} + */ +function downloadModel(url, cb=null) { + return new Promise(resolve=>{ + (async function() { + const model_name = url.split('/').pop(); + + const download_req = await fetch(url); + if(!download_req.ok) { + console.error(download_req.statusText) + resolve(null); + return; + } + + let total_size = download_req.headers.get('Content-Length') + if(!total_size) { + total_size = null; + } else { + total_size = +total_size + } + let downloaded = 0; + + const write_stream = createWriteStream(path.join(model_path, model_name)) + const middle_write_stream = new WritableStream({ + write(chunk) { + write_stream.write(chunk); + + downloaded += chunk.length; + let percentage = total_size ? +((downloaded / total_size) * 100).toFixed(2) : -1; + + cb & cb(percentage, false) + } + }) + + await download_req.body.pipeTo(middle_write_stream) + cb && cb(100, true) + resolve({ + model_name, url, size: total_size, finish_time: Date.now() + }); + })() + }) +} + +module.exports = { + loadModel, + chatCompletions, + abortCompletion, + setClient, + downloadModel, + updateModelSettings +} \ No newline at end of file diff --git a/src/components/App.jsx b/src/components/App.jsx index 0e8256c..0e03468 100644 --- a/src/components/App.jsx +++ b/src/components/App.jsx @@ -3,6 +3,8 @@ import { createBrowserRouter, RouterProvider, } from "react-router-dom"; import Entry from "./Entry"; import router_settings from "../utils/router"; import { createHashRouter } from "react-router-dom"; +import { LOAD_FINISHED, LOAD_PENDING, LOAD_SET_SETTINGS, LOAD_SKIP_SETTINGS } from "../utils/types"; +import Settings from "./settings"; export default function App() { const router = useState( @@ -10,7 +12,14 @@ export default function App() { createHashRouter(router_settings) : createBrowserRouter(router_settings) )[0]; - const [warmup, setWarmUp] = useState(false); + const [load_status, setLoadStatus] = useState(LOAD_PENDING); - return warmup ? : setWarmUp(true)} /> + return ( + load_status === LOAD_PENDING ? + : + load_status === LOAD_FINISHED || load_status === LOAD_SKIP_SETTINGS ? + : + load_status === LOAD_SET_SETTINGS ? + setLoadStatus(LOAD_FINISHED)} /> : <> + ) } \ No newline at end of file diff --git a/src/components/Entry.jsx b/src/components/Entry.jsx index cb6fe06..5db6505 100644 --- a/src/components/Entry.jsx +++ b/src/components/Entry.jsx @@ -1,72 +1,59 @@ import { useEffect, useState } from 'react' -import useIDB from '../utils/idb' -import { downloadModel, isModelDownloaded, loadModel } from '../utils/workers/worker' -import { getPlatformSettings } from '../utils/general_settings'; +import loader from '../utils/start_loader'; +import { LOAD_FINISHED, LOAD_LOADING, LOAD_PENDING, LOAD_FIRST_TIME, LOAD_SET_SETTINGS, LOAD_SKIP_SETTINGS } from '../utils/types'; export default function Entry({complete}) { - const [loadStep, setLoadStep] = useState(0); - const [download_progress, setProgress] = useState(-1); - const idb = useIDB(); + const [loadStep, setLoadStep] = useState(LOAD_PENDING); - async function firstTimeSetup() { - if(!(await isModelDownloaded())) { - setProgress(0); - await downloadModel('completion', (progress)=>{ - setProgress(progress); - }) - } - setLoadStep(2); + async function startUp(status = LOAD_FINISHED) { + await loader(); + complete(status); } - async function startUp() { - localStorage.setItem('not-first-time', '1'); - await idb.initDB(); - if( - loadStep !== 3 && - !getPlatformSettings().enabled_platform && - await isModelDownloaded() - ) await loadModel(); - - complete(); + function waitPreload(loader_function) { + function waitTimeout() { + setTimeout(() => { + if(window['node-llama-cpp']) { + loader_function(); + } else { + waitTimeout(); + } + }, 10); + } + waitTimeout(); } useEffect(()=>{ - loadStep >= 2 && startUp(); - // eslint-disable-next-line - }, [loadStep]) + waitPreload(()=>{ + setLoadStep( + localStorage.getItem('not-first-time') ? + LOAD_LOADING : LOAD_FIRST_TIME + ) + }) + }, []) useEffect(()=>{ - setLoadStep( - 1+!!localStorage.getItem('not-first-time') - ) - }, []) + loadStep === LOAD_LOADING && startUp(); + // eslint-disable-next-line + }, [loadStep]) return (
{ - loadStep === 0 ? + loadStep === LOAD_PENDING ?
Loading, please wait...
: - loadStep === 1 ? + loadStep === LOAD_FIRST_TIME ?
Welcome to SkywardAI Chat!
Seems like this is the first time you using SkywardAI Chat.
- To start chat, you need to download a basic model that is around 400MiB.
- You don't need to download it again in the future
- If you want to use your own model or you want to setup later, please skip. + To start chat, you need to config the models and platforms you want to use.
+ Click the setup button will take you to the settings page
+ OR you can skip for nowand setup anytime you like.
- { - download_progress < 0 ? - <> -
Set Me Up Now!
-
setLoadStep(3)}>Skip for now
- : -
-
-
{Math.round(download_progress)}%
-
- } +
startUp(LOAD_SET_SETTINGS)}>Set Me Up Now!
+
startUp(LOAD_SKIP_SETTINGS)}>Skip for now
:
Loading necessary resources, please wait...
} diff --git a/src/components/chat/Bubbles.jsx b/src/components/chat/Bubbles.jsx new file mode 100644 index 0000000..a816b8e --- /dev/null +++ b/src/components/chat/Bubbles.jsx @@ -0,0 +1,32 @@ +import { useRef } from "react" +import ConversationBubble from "./ConversationBubble" +import { useEffect } from "react" + +export default function Bubbles({ conversation, pending_message }) { + + const mainRef = useRef() + + useEffect(()=>{ + mainRef.current && mainRef.current.scrollTo({ + behavior: "smooth", + top: mainRef.current.scrollHeight + }) + }, [conversation, pending_message]) + + return ( +
+ { conversation.map(({role, content}, idx) => { + return ( + + ) + }) } +
+ ) +} \ No newline at end of file diff --git a/src/components/chat/ChatPage.jsx b/src/components/chat/ChatPage.jsx new file mode 100644 index 0000000..9e44813 --- /dev/null +++ b/src/components/chat/ChatPage.jsx @@ -0,0 +1,26 @@ +import Bubbles from "./Bubbles"; +import TitleBar from "./TitleBar"; +import UserMessage from "./UserMessage"; + +export default function ChatPage({ + chat, chat_history, updateTitle, + sendMessage, pending_message, abort +}) { + + return ( + <> +
{chat.uid?<> + + + : +
+ Please select a conversation or start a new one. +
+ }
+ + ) +} \ No newline at end of file diff --git a/src/components/chat/Conversation.jsx b/src/components/chat/Conversation.jsx deleted file mode 100644 index 83dd984..0000000 --- a/src/components/chat/Conversation.jsx +++ /dev/null @@ -1,226 +0,0 @@ -import { useEffect, useRef, useState } from "react"; -import ConversationBubble from "./ConversationBubble"; -import { CheckCircle, FileImageFill, FileTextFill, Paperclip, PencilFill, Send, StopCircleFill, XCircle } from 'react-bootstrap-icons'; -import useIDB from "../../utils/idb"; -import { isModelLoaded, loadModel } from '../../utils/workers/worker' -import { getCompletionFunctions } from "../../utils/workers"; -import { setClient as setAwsClient } from "../../utils/workers/aws-worker"; -import { setClient as setOpenaiClient } from "../../utils/workers/openai-worker"; - -export default function Conversation({ uid, title, updateTitle, client, updateClient }) { - - const [conversation, setConversation] = useState([]); - const [message, setMessage] = useState(''); - const [pending_message, setPendingMessage] = useState(''); - const [hide_pending, setHidePending] = useState(true); - const [upload_file, setUploadFile] = useState(null); - const [edit_title, toggleEditTitle] = useState(false); - const [edited_title, setEditedTitle] = useState(title); - const chat_functions = useRef(getCompletionFunctions()); - const idb = useIDB(); - - const bubblesRef = useRef(); - - async function getConversationByUid() { - setConversation( - await idb.getAll( - 'messages', - { - where: [{'history-uid': uid}], - select: ['role', 'content'] - } - ) - ); - } - - function messageOnChange(evt) { - setMessage(evt.target.value); - } - - async function sendMessage(evt) { - evt.preventDefault(); - if(!message || !hide_pending) return; - - idb.insert('messages', { - 'history-uid': uid, - role: 'user', - content: message, - createdAt: Date.now() - }) - const user_msg = {role: 'user', content: message} - setConversation([...conversation, user_msg]) - setMessage(''); - - function cb(text, isFinished) { - if(!isFinished) { - setPendingMessage(text); - } else { - setConversation([ - ...conversation, user_msg, - { role: 'assistant', content: text } - ]) - idb.insert('messages', { - 'history-uid': uid, - role: 'assistant', - content: text, - createdAt: Date.now() - }) - idb.updateOne( - 'chat-history', {updatedAt: Date.now()}, [{uid}] - ) - } - } - - let messages = []; - setHidePending(false); - - if(chat_functions.current.platform === "Wllama") { - if(!isModelLoaded()) { - await loadModel('completion', (progress)=>{ - setPendingMessage( - typeof progress === 'number' ? - `**Downloading model, ${progress}% completed**` : - '**Loading model...**' - ) - }); - setPendingMessage('') - } - - messages = - chat_functions.current.continue_chat ? - [...conversation, user_msg] : [user_msg]; - } else { - let user_message = user_msg; - if(upload_file) { - const is_img = upload_file.type.startsWith('image') - const file_obj = { - content: new Uint8Array(await upload_file.arrayBuffer()), - format: upload_file.name.split('.').pop().toLowerCase() - } - if(!is_img) file_obj.name = upload_file.name.split('.').slice(0, -1).join('_'); - user_message[ - is_img ? 'image' : 'document' - ] = file_obj; - setUploadFile(null); - } - messages = [ - ...conversation, - user_message - ] - } - - await chat_functions.current.completions(messages, cb); - setPendingMessage(''); - setHidePending(true); - } - - function submitUpdateTitle() { - if(edited_title && edited_title !== title) { - updateTitle(edited_title); - } - toggleEditTitle(false); - } - - useEffect(()=>{ - uid && getConversationByUid(); - setUploadFile(null); - // eslint-disable-next-line - }, [uid]); - - useEffect(()=>{ - bubblesRef.current && bubblesRef.current.scrollTo({ - behavior: "smooth", - top: bubblesRef.current.scrollHeight - }) - }, [conversation, pending_message]) - - useEffect(()=>{ - setEditedTitle(title); - }, [title]) - - useEffect(()=>{ - if(!chat_functions.current || !uid) return; - - const platform = chat_functions.current.platform - if(platform) { - (async function() { - let set_result = - platform === "AWS" ? await setAwsClient(client) : - platform === "OpenAI" ? await setOpenaiClient(client) : - null; - - if(set_result) { - updateClient(set_result); - } - })() - } - // eslint-disable-next-line - }, [uid]) - - return ( -
- { - uid ? - <> -
- { - edit_title ? -
{evt.preventDefault(); submitUpdateTitle()}}> - setEditedTitle(evt.target.value)} /> - - {setEditedTitle(title); toggleEditTitle(false)}} /> - : -
toggleEditTitle(true)}> -
{ title }
- -
- } -
-
- { conversation.map(({role, content}, idx) => { - return ( - - ) - }) } -
-
-
- { - chat_functions.current && chat_functions.current.platform !== 'Wllama' && -
- { - upload_file ? - upload_file.type.startsWith("image") ? - : : - - } - setUploadFile(evt.target.files.length ? evt.target.files[0] : null)} /> -
- } - -
- { - hide_pending ? - : - - } - -
-
-
- : -
Please select a conversation or start a new one.
- } -
- ) -} \ No newline at end of file diff --git a/src/components/chat/DeleteConfirm.jsx b/src/components/chat/DeleteConfirm.jsx new file mode 100644 index 0000000..98c68e7 --- /dev/null +++ b/src/components/chat/DeleteConfirm.jsx @@ -0,0 +1,29 @@ +import { useEffect } from "react"; +import { useRef } from "react"; + +export default function DeleteConfirm({showConfirm, deleteHistory, resetRequestDelete, conv_to_delete}) { + const dialogRef = useRef(null); + + useEffect(()=>{ + if(dialogRef.current) { + if(showConfirm) dialogRef.current.showModal(); + else dialogRef.current.close(); + } + }, [showConfirm]) + + return ( + +
+ Delete {conv_to_delete && conv_to_delete.title}? +
+
Yes, Delete
+
No, Go Back
+
+ ) +} \ No newline at end of file diff --git a/src/components/chat/Ticket.jsx b/src/components/chat/Ticket.jsx index 9db8a9f..5a1d119 100644 --- a/src/components/chat/Ticket.jsx +++ b/src/components/chat/Ticket.jsx @@ -13,7 +13,7 @@ export default function Ticket({ title, info, selectChat, is_selected, deleteHis onClick={evt=>{ evt.stopPropagation(); deleteHistory({ uid: info.uid, title }) - }} + }} />
) diff --git a/src/components/chat/Tickets.jsx b/src/components/chat/Tickets.jsx index 2e019de..95a5b3a 100644 --- a/src/components/chat/Tickets.jsx +++ b/src/components/chat/Tickets.jsx @@ -3,7 +3,7 @@ import Ticket from "./Ticket"; import useIDB from "../../utils/idb"; import { genRandomID } from "../../utils/tools"; -export default function Tickets({selectChat, current_chat, history, setHistory, deleteHistory}) { +export default function Tickets({selectChat, current_chat, history, setHistory, deleteHistory, platform}) { const idb = useIDB(); @@ -21,7 +21,7 @@ export default function Tickets({selectChat, current_chat, history, setHistory, createdAt: timestamp, updatedAt: timestamp, uid: genRandomID(), - client: null + platform } ) const new_conv_info = await idb.getByID('chat-history', conv_id); diff --git a/src/components/chat/TitleBar.jsx b/src/components/chat/TitleBar.jsx new file mode 100644 index 0000000..670a8ba --- /dev/null +++ b/src/components/chat/TitleBar.jsx @@ -0,0 +1,37 @@ +import { useEffect, useState } from "react"; +import { PencilFill } from "react-bootstrap-icons"; +import { XCircle } from "react-bootstrap-icons"; +import { CheckCircle } from "react-bootstrap-icons"; + +export default function TitleBar({current_title, updateTitle}) { + const [title, setTitle] = useState(current_title); + const [is_editing, toggleEditTitle] = useState(false); + + function submitUpdateTitle() { + if(is_editing && title !== current_title) { + updateTitle(title); + } + toggleEditTitle(false); + } + + useEffect(()=>{ + setTitle(current_title); + }, [current_title]) + + return ( +
+ { + is_editing ? +
{evt.preventDefault(); submitUpdateTitle()}}> + setTitle(evt.target.value)} /> + + {setTitle(current_title); toggleEditTitle(false)}} /> + : +
toggleEditTitle(true)}> +
{ current_title }
+ +
+ } +
+ ) +} \ No newline at end of file diff --git a/src/components/chat/UserMessage.jsx b/src/components/chat/UserMessage.jsx new file mode 100644 index 0000000..ef1834d --- /dev/null +++ b/src/components/chat/UserMessage.jsx @@ -0,0 +1,50 @@ +import { useState } from "react" +import { Paperclip } from "react-bootstrap-icons"; +import { FileTextFill } from "react-bootstrap-icons"; +import { FileImageFill } from "react-bootstrap-icons"; +import { StopCircleFill } from "react-bootstrap-icons"; +import { Send } from "react-bootstrap-icons"; + +export default function UserMessage({ enable_send, file_available, abort_completion, send }) { + + const [message, setMessage] = useState(''); + const [files, setFiles] = useState([]); + + function submitMessage(event) { + event.preventDefault(); + send(message, files); + setMessage(''); + setFiles(''); + } + + return ( +
+
+ { + file_available && +
+ { + files.length ? + files[0].type.startsWith("image") ? + : : + + } + e.name).join('; ')}` : "Select file to append"} + onChange={evt=>setFiles(evt.target.files.length ? evt.target.files[0] : null)} /> +
+ } + setMessage(evt.target.value)}/> +
+ { + enable_send ? + : + + } + +
+
+
+ ) +} \ No newline at end of file diff --git a/src/components/chat/index.jsx b/src/components/chat/index.jsx index 288007e..65654ae 100644 --- a/src/components/chat/index.jsx +++ b/src/components/chat/index.jsx @@ -1,27 +1,81 @@ -import { useEffect, useRef, useState } from "react"; +import { useEffect, useState } from "react"; import Tickets from "./Tickets"; -import Conversation from "./Conversation"; +// import Conversation from "./Conversation"; import useIDB from "../../utils/idb"; +import DeleteConfirm from "./DeleteConfirm"; +import ChatPage from "./ChatPage"; +import { useRef } from "react"; +import { getCompletionFunctions } from "../../utils/workers"; export default function Chat() { const [chat, selectChat] = useState({}); - const [history, setHistory] = useState([]); - const idb = useIDB(); - const dialogRef = useRef(null); - const [showConfirm, toggleConfirm] = useState(false); + const [current_uid, setCurrentUid] = useState(null); + const [chat_history, setChatHistory] = useState([]); + + const [tickets, setTickets] = useState([]); + const [show_delete_confirm, toggleConfirm] = useState(false); const [conv_to_delete, requestDelete] = useState(null); - function updateChatClient(client) { - selectChat({ - ...chat, client + const [pending_message, setPendingMessage] = useState(null); + + const idb = useIDB(); + // const settings = useRef(getCompletionFunctions()); + const settings = useRef(getCompletionFunctions('Llama')); + + async function sendMessage(message, files) { + // save user messages + idb.insert('messages', { + 'history-uid': current_uid, + role: 'user', + content: message, + createdAt: Date.now() }) + // perpare user messages for inference + const user_message = {role: 'user', content: message} + const history_save = [...chat_history, user_message]; + setChatHistory(history_save) + + // the callback function + function cb(content, is_finished) { + if(!is_finished) { + setPendingMessage(content) + } else { + // if response finished, take the content as final response + setPendingMessage(null); + setChatHistory([...history_save, {role: 'assistant', content}]) + // update history in db + idb.insert('messages', { + 'history-uid': current_uid, + role: 'assistant', + content: content, + createdAt: Date.now() + }) + idb.updateOne( + 'chat-history', {updatedAt: Date.now()}, [{uid:current_uid}] + ) + } + } + + // start inference + const send_message = ( + settings.current.formator ? + await settings.current.formator(history_save, files) : history_save + ) + setPendingMessage('') + await settings.current.completions(send_message, cb) + } + + function updateChatClient(client) { + const new_info = {...chat, client} + // if(!chat.settings) new_info.settings = chat.settings; + selectChat(new_info) - let history_cp = [...history]; + let history_cp = [...tickets]; history_cp[ history_cp.findIndex(e=>e.uid === chat.uid) ].client = client; - setHistory(history_cp); + setTickets(history_cp); } function resetRequestDelete() { @@ -35,7 +89,7 @@ export default function Chat() { const {uid} = conv_to_delete; await idb.deleteOne("chat-history", [{uid}]); await idb.deleteAll("messages", [{'history-uid': uid}]); - setHistory(history.filter(e=>e.uid !== uid)); + setTickets(tickets.filter(e=>e.uid !== uid)); uid === chat.uid && selectChat({}); resetRequestDelete(); } @@ -47,49 +101,65 @@ export default function Chat() { ...chat, title: title }) - let history_cp = [...history]; + let history_cp = [...tickets]; history_cp[ history_cp.findIndex(e=>e.uid === chat.uid) ].title = title; - setHistory(history_cp); + setTickets(history_cp); } - useEffect(()=>{ - if(dialogRef.current) { - if(showConfirm) dialogRef.current.showModal(); - else dialogRef.current.close(); - } - }, [showConfirm]) - useEffect(()=>{ conv_to_delete && toggleConfirm(true); }, [conv_to_delete]) + useEffect(()=>{ + if(chat.uid && chat.uid !== current_uid) { + setCurrentUid(chat.uid); + let message_history = null; + // update messages + idb.getAll( + 'messages', + { + where: [{'history-uid': chat.uid}], + select: ['role', 'content'] + } + ).then(messages=>{ + message_history = messages; + setChatHistory(messages) + }).finally(()=>{ + const client = settings.current.initClient(chat.client || null, message_history) + if(!chat.client) { + updateChatClient(client) + } + }) + } + // eslint-disable-next-line + }, [chat]) + return (
- */} + + - -
- Delete {conv_to_delete && conv_to_delete.title}? -
-
Yes, Delete
-
No, Go Back
-
) } \ No newline at end of file diff --git a/src/components/settings/AwsSettings.jsx b/src/components/settings/AwsSettings.jsx index aa7de91..3d9f55f 100644 --- a/src/components/settings/AwsSettings.jsx +++ b/src/components/settings/AwsSettings.jsx @@ -36,9 +36,9 @@ export default function AwsSettings({ trigger, enabled, updateEnabled }) { const credentials = await getJSONCredentials(); if(credentials) { - setAwsKeyID(credentials.key_id); - setAwsSecretKey(credentials.secret_key); - setAwsSessionToken(credentials.session_token); + setAwsKeyID(credentials.key_id || ""); + setAwsSecretKey(credentials.secret_key || ""); + setAwsSessionToken(credentials.session_token || ""); } const { aws_model_id: model_id, aws_region: region } = getPlatformSettings(); diff --git a/src/components/settings/DownloadProtector.jsx b/src/components/settings/DownloadProtector.jsx new file mode 100644 index 0000000..1feb47b --- /dev/null +++ b/src/components/settings/DownloadProtector.jsx @@ -0,0 +1,28 @@ +import { useEffect, useRef } from "react"; + +export default function DownloadProtector({title, description, progress, open_status}) { + + const protectorRef = useRef(); + + useEffect(()=>{ + if(protectorRef.current) { + if(open_status) { + protectorRef.current.showModal(); + } else { + protectorRef.current.close(); + } + } + }, [open_status]) + + return ( + +
+
{title}
+
{description || ""}
+
+
{ progress }%
+
+
+
+ ) +} \ No newline at end of file diff --git a/src/components/settings/LlamaSettings.jsx b/src/components/settings/LlamaSettings.jsx new file mode 100644 index 0000000..7788b73 --- /dev/null +++ b/src/components/settings/LlamaSettings.jsx @@ -0,0 +1,75 @@ +import { useEffect, useState } from "react"; +import SettingSection from "./SettingSection"; +import TrueFalseComponent from "./components/TrueFalseComponent"; +import TextComponent from "./components/TextComponent"; +import useIDB from "../../utils/idb"; +import { getPlatformSettings, updatePlatformSettings } from "../../utils/general_settings"; +import { DEFAULT_LLAMA_CPP_MODEL_URL } from "../../utils/types"; + +export default function LlamaSettings({ trigger, enabled, updateEnabled, openDownloadProtector }) { + + const [model_download_link, setModelDownloadLink] = useState(''); + const idb = useIDB(); + + async function saveSettings() { + const url = model_download_link || DEFAULT_LLAMA_CPP_MODEL_URL + // prevent from leave model url empty + if(url !== model_download_link) setModelDownloadLink(url) + + updatePlatformSettings({ + llama_model_url: url + }) + if(enabled) { + // check if model with this url already downloaded + let stored_model = await idb.getOne("downloaded-models", {where: [{ platform: 'Llama', url }]}) + console.log(stored_model) + // if no model record, means not downloaded + if(!stored_model) { + await openDownloadProtector( + "Please wait while we downloading the model...", + `Downloading model from ${url}`, + async callback=>{ + const model_info = await window['node-llama-cpp'].downloadModel(url, callback) + if(model_info) { + const { model_name, url, size, finish_time } = model_info; + stored_model = { + 'model-name': model_name, + url, size, createdAt: finish_time, + platform: 'Llama' + } + await idb.insert("downloaded-models", stored_model) + } + } + ) + } + // load model using the model name retrieved + await window['node-llama-cpp'].loadModel(stored_model['model-name']) + } + } + + useEffect(()=>{ + trigger && saveSettings(); + // eslint-disable-next-line + }, [trigger]) + + useEffect(()=>{ + const { llama_model_url } = getPlatformSettings(); + setModelDownloadLink(llama_model_url || DEFAULT_LLAMA_CPP_MODEL_URL); + }, []) + + return ( + + + + + ) +} \ No newline at end of file diff --git a/src/components/settings/WllamaSettings.jsx b/src/components/settings/WllamaSettings.jsx index da8a767..c606e1a 100644 --- a/src/components/settings/WllamaSettings.jsx +++ b/src/components/settings/WllamaSettings.jsx @@ -5,7 +5,7 @@ import ScrollBarComponent from "./components/ScrollBarComponent"; import { getPlatformSettings, updatePlatformSettings } from "../../utils/general_settings"; import { loadModel, loadModelSamplingSettings } from "../../utils/workers/worker"; -export default function WllamaSettings({ trigger, enabled }) { +export default function WllamaSettings({ trigger, enabled, updateEnabled }) { const [ threads, setThreads ] = useState(1); const [ batch_size, setBatchSize ] = useState(256); @@ -47,7 +47,12 @@ export default function WllamaSettings({ trigger, enabled }) { }, []) return ( - + + toggleSaveSetting(false), 1000); + complete && complete(); + } + + async function openDownloadProtector(title, description, downloader) { + setDownloadTitle(title); + setDownloadSpec(description); + toggleProtectorOpenStatus(true); + + await downloader((progress, is_finished)=>{ + setDownloadProgress(progress); + if(is_finished) { + toggleProtectorOpenStatus(false); + } + }) } return ( @@ -25,9 +47,17 @@ export default function Settings() { + updatePlatform(set ? "Llama" : null)} + openDownloadProtector={openDownloadProtector} + /> updatePlatform(set ? "Wllama" : null)} + openDownloadProtector={openDownloadProtector} /> { saveSettingTrigger ? "Settings Saved!" : "Save Settings" } + ) } \ No newline at end of file diff --git a/src/styles/settings.css b/src/styles/settings.css index 4b99b5a..f628fd4 100644 --- a/src/styles/settings.css +++ b/src/styles/settings.css @@ -162,4 +162,44 @@ height: 100%; width: var(--text-width); margin-left: var(--elem-margin); +} + +dialog:has(.download-protector) { + border: none; + border-radius: 15px; + background-color: white; +} + +.download-protector { + width: 500px; + height: fit-content; + max-height: 200px; +} + +.download-protector > .title { + text-align: center; + font-size: 18px; + height: 25px; +} + +.download-protector > .description { + word-wrap: break-word; + margin: 7px 0px; + max-height: 130px; + overflow-y: auto; + margin-bottom: 10px; +} + +.download-protector > .progress-bar { + width: 100%; + height: 20px; + border: 1px solid gray; + border-radius: 15px; + text-align: center; + font-size: 13px; + align-content: center; + + background-image: linear-gradient(to right, limegreen 50%, white 50%); + background-size: 200% 100%; + background-position-x: 100%; } \ No newline at end of file diff --git a/src/utils/general_settings.js b/src/utils/general_settings.js index 225bbe2..f5104b5 100644 --- a/src/utils/general_settings.js +++ b/src/utils/general_settings.js @@ -1,4 +1,16 @@ const PLATFORM_SETTINGS_KEY = 'platform-settings' +/** + * @typedef PlatformSettings + * @property {"Wllama"|"Llama"|"AWS"|"OpenAI"} enabled_platform + * @property {String} aws_model_id + * @property {String} aws_region + * @property {String} openai_model + * @property {Number} wllama_threads + * @property {Number} wllama_batch_size + * @property {Number} wllama_context_length + * @property {Boolean} wllama_continue_conv + * @property {String} llama_model_url + */ const DEFAULT_PLATFORM_SETTINGS = { enabled_platform: null, // aws @@ -9,10 +21,18 @@ const DEFAULT_PLATFORM_SETTINGS = { wllama_threads: 4, wllama_batch_size: 128, wllama_context_length: 4096, - wllama_continue_conv: false + wllama_continue_conv: false, + // llama + llama_model_url: '' } const MODEL_SETTINGS_KEY = 'general-model-settings' +/** + * @typedef ModelSettings + * @property {Number} max_tokens + * @property {Number} top_p + * @property {Number} temperature + */ const DEFAULT_MODEL_SETTINGS = { max_tokens: 128, top_p: 0.9, @@ -33,6 +53,10 @@ function loadSettings(key, default_settings) { let model_settings = loadSettings(MODEL_SETTINGS_KEY, DEFAULT_MODEL_SETTINGS); +/** + * get current general model sampling settings + * @returns {ModelSettings} + */ export function getModelSettings() { return model_settings; } @@ -49,6 +73,10 @@ export function updateModelSettings(settings) { let platform_settings = loadSettings(PLATFORM_SETTINGS_KEY, DEFAULT_PLATFORM_SETTINGS); +/** + * get platform related settings + * @returns {PlatformSettings} + */ export function getPlatformSettings() { return platform_settings; } diff --git a/src/utils/idb/settings.js b/src/utils/idb/settings.js index 47c3a2b..141b661 100644 --- a/src/utils/idb/settings.js +++ b/src/utils/idb/settings.js @@ -31,5 +31,24 @@ export const versions = [ { name: 'json' } ] } - } + }, + { + 'chat-history': { + columns: [ + { name: 'platform' }, + ] + } + }, + { + 'downloaded-models': { + op: 'new', + columns: [ + { name: 'model-name' }, + { name: 'url' }, + { name: 'platform' }, + { name: 'size' }, + { name: 'createdAt' }, + ] + } + }, ] \ No newline at end of file diff --git a/src/utils/start_loader.js b/src/utils/start_loader.js new file mode 100644 index 0000000..974fb7a --- /dev/null +++ b/src/utils/start_loader.js @@ -0,0 +1,23 @@ +import { getPlatformSettings } from "./general_settings"; +import { instance } from "./idb"; +import { loadModel } from "./workers/worker"; + +export default async function loader() { + localStorage.setItem('not-first-time', '1'); + await instance.initDB(); + + const settings = getPlatformSettings(); + let info; + + switch(settings.enabled_platform) { + case "Wllama": + await loadModel(); + return; + case "Llama": + info = await instance.getOne('downloaded-models', {where: [{platform: "Llama", url: settings.llama_model_url}]}) + if(info) { + await window['node-llama-cpp'].loadModel(info['model-name']); + } + return; + } +} \ No newline at end of file diff --git a/src/utils/types.js b/src/utils/types.js new file mode 100644 index 0000000..a607171 --- /dev/null +++ b/src/utils/types.js @@ -0,0 +1,9 @@ +export const LOAD_PENDING = 0; +export const LOAD_LOADING = 1; +export const LOAD_FIRST_TIME = 2; + +export const LOAD_FINISHED = 1; +export const LOAD_SET_SETTINGS = 2; +export const LOAD_SKIP_SETTINGS = 3; + +export const DEFAULT_LLAMA_CPP_MODEL_URL = "https://huggingface.co/aisuko/Phi-3-mini-4k-instruct-gguf/resolve/main/Phi3-mini-4k-instruct-Q4.gguf" \ No newline at end of file diff --git a/src/utils/workers/aws-worker.js b/src/utils/workers/aws-worker.js index 1248e43..b598113 100644 --- a/src/utils/workers/aws-worker.js +++ b/src/utils/workers/aws-worker.js @@ -55,24 +55,28 @@ export async function initBedrockClient() { let abort_signal = false; /** - * @typedef ImageMessage - * @property {"png" | "jpeg" | "gif" | "webp"} format Format of image - * @property {Uint8Array} content Content in bytes + * @typedef AWSInferenceFileSource + * @property {Uint8Array} bytes The file content in Uint8Array */ /** - * @typedef DocumentMessage - * @property { "pdf" | "csv" | "doc" | "docx" | "xls" | "xlsx" | "html" | "txt" | "md"} format Format of the document - * @property {String} name Name of the document - * @property {Uint8Array} content Content in bytes + * @typedef AWSInferenceFile + * @property {String|undefined} name Only when the file type is `document` requires this + * @property {String} format The format of file + * @property {AWSInferenceFileSource} source source of the file + */ + +/** + * @typedef AWSInferenceContent + * @property {String} text Text to send + * @property {AWSInferenceFile} image image to be sent, max 20 in one sesion + * @property {AWSInferenceFile} document document to be sent, max 5 in one session */ /** * @typedef Message * @property {"user"|"assistant"|"system"} role Sender - * @property {String} content Message content - * @property {ImageMessage?} image Optional, send model an image for reference - * @property {DocumentMessage?} document Optional, send model a document for reference + * @property {AWSInferenceContent} content Message content, can format using `formator()` */ /** @@ -111,32 +115,14 @@ export async function chatCompletions(messages, cb = null) { const system = []; const normal_messages = []; - messages.forEach(({ role, content, image, document })=>{ + messages.forEach(message=>{ + const { role } = message; + if(role === 'system') { - system.push({text: content}); - return; - } - const message = { - role, content: [{text: content}] + system.push(message); + } else { + normal_messages.push(message); } - if(image) { - message.content.push( - { image: { - format: image.format, - source: { bytes: image.content } - } } - ) - } - if(document) { - message.content.push( - { document: { - format: document.format, - name: document.name, - source: { bytes: document.content } - } } - ) - } - normal_messages.push(message); }) const { max_tokens:maxTokens, top_p:topP, temperature } = getModelSettings(); @@ -184,4 +170,56 @@ export async function chatCompletions(messages, cb = null) { export function abortCompletion() { abort_signal = true; +} + +export async function formator(messages, files = []) { + let last_role; + + const common_messages = []; + const system_messages = []; + + for(const message of messages) { + const { role, content } = message; + const msg = {role, content: [{text:content}]}; + // if user asked for twice, ignore the last one + if(/^(user|assistant)$/.test(role)) { + role === last_role && common_messages.pop(); + last_role = role; + common_messages.push(msg) + } else { + system_messages.push(msg) + } + } + + // append files + if(files.length) { + for(const file of files) { + const file_info = file.name.split('.') + const extension = file_info.pop(); + const filename = file_info.join('_'); + const bytes = await file.arrayBuffer() + + if(/^image\/.+/.test(file.type)) { + common_messages[common_messages.length - 1].content.push( + { + image: { + format: extension, + source: { bytes } + } + } + ) + } else { + common_messages[common_messages.length - 1].content.push( + { + document: { + name: filename, + format: extension, + source: { bytes } + } + } + ) + } + } + } + return [...common_messages, ...system_messages] } \ No newline at end of file diff --git a/src/utils/workers/index.js b/src/utils/workers/index.js index 1b1d61e..5cdeddb 100644 --- a/src/utils/workers/index.js +++ b/src/utils/workers/index.js @@ -1,32 +1,57 @@ -import { getPlatformSettings } from "../general_settings"; +import { getModelSettings, getPlatformSettings } from "../general_settings"; import { chatCompletions as WllamaCompletions, abortCompletion as WllamaAbort } from "./worker"; -import { chatCompletions as AwsCompletions, abortCompletion as AwsAbort } from "./aws-worker" -import { chatCompletions as OpenaiCompletions, abortCompletion as OpenaiAbort } from "./openai-worker"; +import { chatCompletions as AwsCompletions, abortCompletion as AwsAbort, setClient as AwsSetClient, formator as AwsFormator } from "./aws-worker" +import { chatCompletions as OpenaiCompletions, abortCompletion as OpenaiAbort, setClient as OpenAISetClient } from "./openai-worker"; /** * @typedef CompletionFunctions * @property {Function} completions * @property {Function} abort - * @property {"Wllama" | "AWS" | "OpenAI"} platform + * @property {Function} initClient + * @property {"Wllama" | "AWS" | "OpenAI" | "Llama"} platform + * @property {Promise>|undefined} formator */ /** * Get completion and abort functions of selected platform * @returns {CompletionFunctions} */ -export function getCompletionFunctions() { - const platform_settings = getPlatformSettings(); +export function getCompletionFunctions(platform = null) { + platform = platform || getPlatformSettings().enabled_platform; - switch(platform_settings.enabled_platform ) { + switch(platform) { case 'AWS': - return { completions: AwsCompletions, abort: AwsAbort, platform: "AWS" } + return { + completions: AwsCompletions, + abort: AwsAbort, platform: "AWS", + initClient: AwsSetClient, + formator: AwsFormator + } case 'OpenAI': - return { completions: OpenaiCompletions, abort: OpenaiAbort, platform: "OpenAI"} - default: return { - completions: WllamaCompletions, abort: WllamaAbort, - platform: "Wllama", continue_chat: platform_settings.wllama_continue_conv + completions: OpenaiCompletions, + abort: OpenaiAbort, platform: "OpenAI", + initClient: OpenAISetClient + } + case 'Llama': + window['node-llama-cpp'].updateModelSettings(getModelSettings()) + return { + completions: window['node-llama-cpp'].chatCompletions, + abort: window['node-llama-cpp'].abortCompletion, + platform: 'Llama', + initClient: window['node-llama-cpp'].setClient + } + case "Wllama": + return { + completions: WllamaCompletions, + abort: WllamaAbort, + platform: "Wllama" } + // default: + // return { + // completions: WllamaCompletions, abort: WllamaAbort, + // platform: "Wllama" + // } } } \ No newline at end of file