commit 1f01c0c4547bdc12013298db8495fd6ddf017f85 Author: BordedDev <> Date: Thu Mar 6 00:36:52 2025 +0100 Add base bot setup - supports ping, llama and image/comfyUI - comes with 3 pre-setup comfyUI templates diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..3c924dd --- /dev/null +++ b/.gitignore @@ -0,0 +1,132 @@ +/.idea/ +/.vscode/ +/node_modules +.env +*.orig +*.pyc +*.swp +*~ +.fuse_hidden* +.directory +.Trash-* +.nfs* +.idea/**/workspace.xml +.idea/**/tasks.xml +.idea/**/usage.statistics.xml +.idea/**/dictionaries +.idea/**/shelf +.idea/**/aws.xml +.idea/**/contentModel.xml +.idea/**/dataSources/ +.idea/**/dataSources.ids +.idea/**/dataSources.local.xml +.idea/**/sqlDataSources.xml +.idea/**/dynamic.xml +.idea/**/uiDesigner.xml +.idea/**/dbnavigator.xml +.idea/**/gradle.xml +.idea/**/libraries +cmake-build-*/ +.idea/**/mongoSettings.xml +*.iws +out/ +.idea_modules/ +atlassian-ide-plugin.xml +.idea/replstate.xml +.idea/sonarlint/ +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties +.idea/httpRequests +.idea/caches/build_file_checksums.ser +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* +report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json +pids +*.pid +*.seed +*.pid.lock +lib-cov +coverage +*.lcov +.nyc_output +.grunt +bower_components +.lock-wscript +build/Release +node_modules/ +jspm_packages/ +web_modules/ +*.tsbuildinfo +.npm +.eslintcache +.stylelintcache +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ +.node_repl_history +*.tgz +.yarn-integrity +.env.development.local +.env.test.local +.env.production.local +.env.local +.cache +.parcel-cache +.next +out +.nuxt +dist +.cache/ +.vuepress/dist +.temp +.docusaurus +.serverless/ +.fusebox/ +.dynamodb/ +.tern-port +.vscode-test +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* +.svelte-kit/ +package +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db +*.stackdump +[Dd]esktop.ini +$RECYCLE.BIN/ +*.cab +*.msi +*.msix +*.msm +*.msp +*.lnk +.DS_Store +.AppleDouble +.LSOverride +Icon +._* +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk diff --git a/deno.json b/deno.json new file mode 100644 index 0000000..fdcc99e --- /dev/null +++ b/deno.json @@ -0,0 +1,24 @@ +{ + "tasks": { + "dev:snek-llama-bot": "deno run --allow-env --allow-read --allow-sys --allow-ffi --allow-net=snek.molodetz.nl:443,127.0.0.1:8188 --allow-run=\"deno\" src/ws-snek-llama-bot.ts", + "dev:snek-img-bot": "deno run --allow-env --allow-read --allow-sys --allow-ffi --allow-net=snek.molodetz.nl:443,127.0.0.1:8188 --allow-run=\"deno\" src/ws-snek-image-bot.ts" + }, + "imports": { + "@eta-dev/eta": "jsr:@eta-dev/eta@^3.5.0", + "@logtape/logtape": "jsr:@logtape/logtape@^0.8.1", + "@std/assert": "jsr:@std/assert@1", + "@std/cli": "jsr:@std/cli@^1.0.12", + "@std/collections": "jsr:@std/collections@^1.0.10", + "@std/dotenv": "jsr:@std/dotenv@^0.225.3", + "@std/path": "jsr:@std/path@^1.0.8", + "@types/node": "npm:@types/node@^22.13.9", + "jmespath": "npm:jmespath@^0.16.0", + "lodash-es": "npm:lodash-es@^4.17.21", + "node-llama-cpp": "npm:node-llama-cpp@^3.6.0", + "octokit": "npm:octokit@^4.1.0" + }, + "fmt": { + "semiColons": false + }, + "nodeModulesDir": "auto" +} diff --git a/deno.lock b/deno.lock new file mode 100644 index 0000000..fff14f9 --- /dev/null +++ b/deno.lock @@ -0,0 +1,1259 @@ +{ + "version": "4", + "specifiers": { + "jsr:@eta-dev/eta@*": "3.5.0", + "jsr:@eta-dev/eta@^3.5.0": "3.5.0", + "jsr:@logtape/logtape@~0.8.1": "0.8.1", + "jsr:@std/assert@1": "1.0.11", + "jsr:@std/cli@^1.0.12": "1.0.12", + "jsr:@std/collections@^1.0.10": "1.0.10", + "jsr:@std/dotenv@~0.225.3": "0.225.3", + "jsr:@std/internal@^1.0.5": "1.0.5", + "jsr:@std/path@*": "1.0.8", + "jsr:@std/path@^1.0.8": "1.0.8", + "npm:@types/node@^22.13.9": "22.13.9", + "npm:jmespath@*": "0.16.0", + "npm:jmespath@0.16": "0.16.0", + "npm:lodash-es@*": "4.17.21", + "npm:lodash-es@^4.17.21": "4.17.21", + "npm:node-llama-cpp@*": "3.6.0", + "npm:node-llama-cpp@^3.6.0": "3.6.0", + "npm:octokit@*": "4.1.0_@octokit+core@6.1.3", + "npm:octokit@^4.1.0": "4.1.0_@octokit+core@6.1.3" + }, + "jsr": { + "@eta-dev/eta@3.5.0": { + "integrity": "6b70827efc14c7cbf08498ac7a922ecab003641caf3852a6cb5b1b12ee58fb37" + }, + "@logtape/logtape@0.8.1": { + "integrity": "deb3b276d4be0a697e94f6a79ddb309f993e1870166a6d43d8eca86cd00871a8" + }, + "@std/assert@1.0.11": { + "integrity": "2461ef3c368fe88bc60e186e7744a93112f16fd110022e113a0849e94d1c83c1", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/cli@1.0.12": { + "integrity": "e5cfb7814d189da174ecd7a34fbbd63f3513e24a1b307feb2fcd5da47a070d90" + }, + "@std/collections@1.0.10": { + "integrity": "903af106a3d92970d74e20f7ebff77d9658af9bef4403f1dc42a7801c0575899" + }, + "@std/dotenv@0.225.3": { + "integrity": "a95e5b812c27b0854c52acbae215856d9cce9d4bbf774d938c51d212711e8d4a" + }, + "@std/internal@1.0.5": { + "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" + }, + "@std/path@1.0.8": { + "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" + } + }, + "npm": { + "@huggingface/jinja@0.3.3": { + "integrity": "sha512-vQQr2JyWvVFba3Lj9es4q9vCl1sAc74fdgnEMoX8qHrXtswap9ge9uO3ONDzQB0cQ0PUyaKY2N6HaVbTBvSXvw==" + }, + "@kwsites/file-exists@1.1.1": { + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", + "dependencies": [ + "debug" + ] + }, + "@kwsites/promise-deferred@1.1.1": { + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" + }, + "@node-llama-cpp/linux-arm64@3.6.0": { + "integrity": "sha512-hE/hqxtr5DQyY1DohwOcY742NQZtEFag8H/FQP2Y7fnlNQYhiOe45PcAJDiqmEUMmlCGVvHZaCWbaNVoTMYdWg==" + }, + "@node-llama-cpp/linux-armv7l@3.6.0": { + "integrity": "sha512-aRyDVf8szfJJWHnNWG56Ir3LtfXxj9vwLXbXy4XwfHlMTuBHWhmrRXyB8f3A/aJ8h6u48wMVxqxdmwnXigSKWg==" + }, + "@node-llama-cpp/linux-x64-cuda@3.6.0": { + "integrity": "sha512-lS9F+aX2cGV1I/pAuCNeQm9bGELNmnvKqbF4k4ZjNk64ZT2sE74o2S/uN6GvMJETG+rgQiKRuKb1l/yIm0LOfA==" + }, + "@node-llama-cpp/linux-x64-vulkan@3.6.0": { + "integrity": "sha512-1Wc6e1YJRpjllD6MRfwYPxE7z8qvmaYrEFyVPzTe9sghKXUswpBmmb0mM/yOzwT/mUBygSwOEBvTkp3nG+pWhg==" + }, + "@node-llama-cpp/linux-x64@3.6.0": { + "integrity": "sha512-lUzTTY7AwRz5j/f6rss6fPc2u3YNOmo4k8Zap38kzy9H6rL+U2nlanN+4STs5j/7gcx5f/VHRnPrYDl5OPcmTw==" + }, + "@node-llama-cpp/mac-arm64-metal@3.6.0": { + "integrity": "sha512-bOtZkJ6dCWHnZ1SP8EJ+LOdIFKo/7clb0ck+IwD/Bn/2ePzObVBsq30IxpRnUXx8pZ54+CzmTQuS2NOMHXS0PQ==" + }, + "@node-llama-cpp/mac-x64@3.6.0": { + "integrity": "sha512-xjyEAsOXQ6i3VuXoQYB5llYuNz0sP9YnrDzAJ8sqovXXYkSyXPRyTCF5/PaAFc6QMkpsFIw3fSbavJeSzR5IGw==" + }, + "@node-llama-cpp/win-arm64@3.6.0": { + "integrity": "sha512-o4gEUBVMZ1R3Oy1f642UA1vJtnVLAJq2W+diPUxJVqXs9KYDOf7+JuxVcTEzSj6+wBsN3ZRtt36Xst41Jwp6FQ==" + }, + "@node-llama-cpp/win-x64-cuda@3.6.0": { + "integrity": "sha512-vxNrz4BwMNgmfbRxALdTnb7RlJnO6p5uXlZP8fxpaD0zyBllenURTTzEo3Wobpa98af5DWEY1AueH9RFixvscA==" + }, + "@node-llama-cpp/win-x64-vulkan@3.6.0": { + "integrity": "sha512-2XhzVQaRw5QxMqtg+517W+tn0fgDqvo12I0/wVpaBctwIaX+yOcj+njGlVUbMBFzhR9VM9wo5N2bjfRYI6y+PA==" + }, + "@node-llama-cpp/win-x64@3.6.0": { + "integrity": "sha512-JDJoDeBkJhvFlINwi7tyTuOjSTJoBF6yyf7o89iMZ2xniyo6BzhI2d/79PGLkXht/1+sGNoCyzbuz3cBgP06Fg==" + }, + "@octokit/app@15.1.2_@octokit+core@6.1.3": { + "integrity": "sha512-6aKmKvqnJKoVK+kx0mLlBMKmQYoziPw4Rd/PWr0j65QVQlrDXlu6hGU8fmTXt7tNkf/DsubdIaTT4fkoWzCh5g==", + "dependencies": [ + "@octokit/auth-app", + "@octokit/auth-unauthenticated", + "@octokit/core", + "@octokit/oauth-app", + "@octokit/plugin-paginate-rest", + "@octokit/types", + "@octokit/webhooks" + ] + }, + "@octokit/auth-app@7.1.4": { + "integrity": "sha512-5F+3l/maq9JfWQ4bV28jT2G/K8eu9OJ317yzXPTGe4Kw+lKDhFaS4dQ3Ltmb6xImKxfCQdqDqMXODhc9YLipLw==", + "dependencies": [ + "@octokit/auth-oauth-app", + "@octokit/auth-oauth-user", + "@octokit/request", + "@octokit/request-error", + "@octokit/types", + "toad-cache", + "universal-github-app-jwt", + "universal-user-agent" + ] + }, + "@octokit/auth-oauth-app@8.1.2": { + "integrity": "sha512-3woNZgq5/S6RS+9ZTq+JdymxVr7E0s4EYxF20ugQvgX3pomdPUL5r/XdTY9wALoBM2eHVy4ettr5fKpatyTyHw==", + "dependencies": [ + "@octokit/auth-oauth-device", + "@octokit/auth-oauth-user", + "@octokit/request", + "@octokit/types", + "universal-user-agent" + ] + }, + "@octokit/auth-oauth-device@7.1.2": { + "integrity": "sha512-gTOIzDeV36OhVfxCl69FmvJix7tJIiU6dlxuzLVAzle7fYfO8UDyddr9B+o4CFQVaMBLMGZ9ak2CWMYcGeZnPw==", + "dependencies": [ + "@octokit/oauth-methods", + "@octokit/request", + "@octokit/types", + "universal-user-agent" + ] + }, + "@octokit/auth-oauth-user@5.1.2": { + "integrity": "sha512-PgVDDPJgZYb3qSEXK4moksA23tfn68zwSAsQKZ1uH6IV9IaNEYx35OXXI80STQaLYnmEE86AgU0tC1YkM4WjsA==", + "dependencies": [ + "@octokit/auth-oauth-device", + "@octokit/oauth-methods", + "@octokit/request", + "@octokit/types", + "universal-user-agent" + ] + }, + "@octokit/auth-token@5.1.2": { + "integrity": "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw==" + }, + "@octokit/auth-unauthenticated@6.1.1": { + "integrity": "sha512-bGXqdN6RhSFHvpPq46SL8sN+F3odQ6oMNLWc875IgoqcC3qus+fOL2th6Tkl94wvdSTy8/OeHzWy/lZebmnhog==", + "dependencies": [ + "@octokit/request-error", + "@octokit/types" + ] + }, + "@octokit/core@6.1.3": { + "integrity": "sha512-z+j7DixNnfpdToYsOutStDgeRzJSMnbj8T1C/oQjB6Aa+kRfNjs/Fn7W6c8bmlt6mfy3FkgeKBRnDjxQow5dow==", + "dependencies": [ + "@octokit/auth-token", + "@octokit/graphql", + "@octokit/request", + "@octokit/request-error", + "@octokit/types", + "before-after-hook", + "universal-user-agent" + ] + }, + "@octokit/endpoint@10.1.2": { + "integrity": "sha512-XybpFv9Ms4hX5OCHMZqyODYqGTZ3H6K6Vva+M9LR7ib/xr1y1ZnlChYv9H680y77Vd/i/k+thXApeRASBQkzhA==", + "dependencies": [ + "@octokit/types", + "universal-user-agent" + ] + }, + "@octokit/graphql@8.2.0": { + "integrity": "sha512-gejfDywEml/45SqbWTWrhfwvLBrcGYhOn50sPOjIeVvH6i7D16/9xcFA8dAJNp2HMcd+g4vru41g4E2RBiZvfQ==", + "dependencies": [ + "@octokit/request", + "@octokit/types", + "universal-user-agent" + ] + }, + "@octokit/oauth-app@7.1.5": { + "integrity": "sha512-/Y2MiwWDlGUK4blKKfjJiwjzu/FzwKTTTfTZAAQ0QbdBIDEGJPWhOFH6muSN86zaa4tNheB4YS3oWIR2e4ydzA==", + "dependencies": [ + "@octokit/auth-oauth-app", + "@octokit/auth-oauth-user", + "@octokit/auth-unauthenticated", + "@octokit/core", + "@octokit/oauth-authorization-url", + "@octokit/oauth-methods", + "@types/aws-lambda", + "universal-user-agent" + ] + }, + "@octokit/oauth-authorization-url@7.1.1": { + "integrity": "sha512-ooXV8GBSabSWyhLUowlMIVd9l1s2nsOGQdlP2SQ4LnkEsGXzeCvbSbCPdZThXhEFzleGPwbapT0Sb+YhXRyjCA==" + }, + "@octokit/oauth-methods@5.1.3": { + "integrity": "sha512-M+bDBi5H8FnH0xhCTg0m9hvcnppdDnxUqbZyOkxlLblKpLAR+eT2nbDPvJDp0eLrvJWA1I8OX0KHf/sBMQARRA==", + "dependencies": [ + "@octokit/oauth-authorization-url", + "@octokit/request", + "@octokit/request-error", + "@octokit/types" + ] + }, + "@octokit/openapi-types@23.0.1": { + "integrity": "sha512-izFjMJ1sir0jn0ldEKhZ7xegCTj/ObmEDlEfpFrx4k/JyZSMRHbO3/rBwgE7f3m2DHt+RrNGIVw4wSmwnm3t/g==" + }, + "@octokit/openapi-webhooks-types@8.5.1": { + "integrity": "sha512-i3h1b5zpGSB39ffBbYdSGuAd0NhBAwPyA3QV3LYi/lx4lsbZiu7u2UHgXVUR6EpvOI8REOuVh1DZTRfHoJDvuQ==" + }, + "@octokit/plugin-paginate-graphql@5.2.4_@octokit+core@6.1.3": { + "integrity": "sha512-pLZES1jWaOynXKHOqdnwZ5ULeVR6tVVCMm+AUbp0htdcyXDU95WbkYdU4R2ej1wKj5Tu94Mee2Ne0PjPO9cCyA==", + "dependencies": [ + "@octokit/core" + ] + }, + "@octokit/plugin-paginate-rest@11.4.0_@octokit+core@6.1.3": { + "integrity": "sha512-ttpGck5AYWkwMkMazNCZMqxKqIq1fJBNxBfsFwwfyYKTf914jKkLF0POMS3YkPBwp5g1c2Y4L79gDz01GhSr1g==", + "dependencies": [ + "@octokit/core", + "@octokit/types" + ] + }, + "@octokit/plugin-rest-endpoint-methods@13.3.0_@octokit+core@6.1.3": { + "integrity": "sha512-LUm44shlmkp/6VC+qQgHl3W5vzUP99ZM54zH6BuqkJK4DqfFLhegANd+fM4YRLapTvPm4049iG7F3haANKMYvQ==", + "dependencies": [ + "@octokit/core", + "@octokit/types" + ] + }, + "@octokit/plugin-retry@7.1.3_@octokit+core@6.1.3": { + "integrity": "sha512-8nKOXvYWnzv89gSyIvgFHmCBAxfQAOPRlkacUHL9r5oWtp5Whxl8Skb2n3ACZd+X6cYijD6uvmrQuPH/UCL5zQ==", + "dependencies": [ + "@octokit/core", + "@octokit/request-error", + "@octokit/types", + "bottleneck" + ] + }, + "@octokit/plugin-throttling@9.4.0_@octokit+core@6.1.3": { + "integrity": "sha512-IOlXxXhZA4Z3m0EEYtrrACkuHiArHLZ3CvqWwOez/pURNqRuwfoFlTPbN5Muf28pzFuztxPyiUiNwz8KctdZaQ==", + "dependencies": [ + "@octokit/core", + "@octokit/types", + "bottleneck" + ] + }, + "@octokit/request-error@6.1.6": { + "integrity": "sha512-pqnVKYo/at0NuOjinrgcQYpEbv4snvP3bKMRqHaD9kIsk9u1LCpb2smHZi8/qJfgeNqLo5hNW4Z7FezNdEo0xg==", + "dependencies": [ + "@octokit/types" + ] + }, + "@octokit/request@9.2.0": { + "integrity": "sha512-kXLfcxhC4ozCnAXy2ff+cSxpcF0A1UqxjvYMqNuPIeOAzJbVWQ+dy5G2fTylofB/gTbObT8O6JORab+5XtA1Kw==", + "dependencies": [ + "@octokit/endpoint", + "@octokit/request-error", + "@octokit/types", + "fast-content-type-parse", + "universal-user-agent" + ] + }, + "@octokit/types@13.8.0": { + "integrity": "sha512-x7DjTIbEpEWXK99DMd01QfWy0hd5h4EN+Q7shkdKds3otGQP+oWE/y0A76i1OvH9fygo4ddvNf7ZvF0t78P98A==", + "dependencies": [ + "@octokit/openapi-types" + ] + }, + "@octokit/webhooks-methods@5.1.0": { + "integrity": "sha512-yFZa3UH11VIxYnnoOYCVoJ3q4ChuSOk2IVBBQ0O3xtKX4x9bmKb/1t+Mxixv2iUhzMdOl1qeWJqEhouXXzB3rQ==" + }, + "@octokit/webhooks@13.5.0": { + "integrity": "sha512-uSO/TCCfi9vaZHOBsGWsRNBXYYKtLnSDbHI+std0M80AaEd7AnVfLqvk+9V3GP1faPcOx06ADx+h8UWwvemIGw==", + "dependencies": [ + "@octokit/openapi-webhooks-types", + "@octokit/request-error", + "@octokit/webhooks-methods" + ] + }, + "@reflink/reflink-darwin-arm64@0.1.19": { + "integrity": "sha512-ruy44Lpepdk1FqDz38vExBY/PVUsjxZA+chd9wozjUH9JjuDT/HEaQYA6wYN9mf041l0yLVar6BCZuWABJvHSA==" + }, + "@reflink/reflink-darwin-x64@0.1.19": { + "integrity": "sha512-By85MSWrMZa+c26TcnAy8SDk0sTUkYlNnwknSchkhHpGXOtjNDUOxJE9oByBnGbeuIE1PiQsxDG3Ud+IVV9yuA==" + }, + "@reflink/reflink-linux-arm64-gnu@0.1.19": { + "integrity": "sha512-7P+er8+rP9iNeN+bfmccM4hTAaLP6PQJPKWSA4iSk2bNvo6KU6RyPgYeHxXmzNKzPVRcypZQTpFgstHam6maVg==" + }, + "@reflink/reflink-linux-arm64-musl@0.1.19": { + "integrity": "sha512-37iO/Dp6m5DDaC2sf3zPtx/hl9FV3Xze4xoYidrxxS9bgP3S8ALroxRK6xBG/1TtfXKTvolvp+IjrUU6ujIGmA==" + }, + "@reflink/reflink-linux-x64-gnu@0.1.19": { + "integrity": "sha512-jbI8jvuYCaA3MVUdu8vLoLAFqC+iNMpiSuLbxlAgg7x3K5bsS8nOpTRnkLF7vISJ+rVR8W+7ThXlXlUQ93ulkw==" + }, + "@reflink/reflink-linux-x64-musl@0.1.19": { + "integrity": "sha512-e9FBWDe+lv7QKAwtKOt6A2W/fyy/aEEfr0g6j/hWzvQcrzHCsz07BNQYlNOjTfeytrtLU7k449H1PI95jA4OjQ==" + }, + "@reflink/reflink-win32-arm64-msvc@0.1.19": { + "integrity": "sha512-09PxnVIQcd+UOn4WAW73WU6PXL7DwGS6wPlkMhMg2zlHHG65F3vHepOw06HFCq+N42qkaNAc8AKIabWvtk6cIQ==" + }, + "@reflink/reflink-win32-x64-msvc@0.1.19": { + "integrity": "sha512-E//yT4ni2SyhwP8JRjVGWr3cbnhWDiPLgnQ66qqaanjjnMiu3O/2tjCPQXlcGc/DEYofpDc9fvhv6tALQsMV9w==" + }, + "@reflink/reflink@0.1.19": { + "integrity": "sha512-DmCG8GzysnCZ15bres3N5AHCmwBwYgp0As6xjhQ47rAUTUXxJiK+lLUxaGsX3hd/30qUpVElh05PbGuxRPgJwA==", + "dependencies": [ + "@reflink/reflink-darwin-arm64", + "@reflink/reflink-darwin-x64", + "@reflink/reflink-linux-arm64-gnu", + "@reflink/reflink-linux-arm64-musl", + "@reflink/reflink-linux-x64-gnu", + "@reflink/reflink-linux-x64-musl", + "@reflink/reflink-win32-arm64-msvc", + "@reflink/reflink-win32-x64-msvc" + ] + }, + "@tinyhttp/content-disposition@2.2.2": { + "integrity": "sha512-crXw1txzrS36huQOyQGYFvhTeLeG0Si1xu+/l6kXUVYpE0TjFjEZRqTbuadQLfKGZ0jaI+jJoRyqaWwxOSHW2g==" + }, + "@types/aws-lambda@8.10.147": { + "integrity": "sha512-nD0Z9fNIZcxYX5Mai2CTmFD7wX7UldCkW2ezCF8D1T5hdiLsnTWDGRpfRYntU6VjTdLQjOvyszru7I1c1oCQew==" + }, + "@types/node@22.13.9": { + "integrity": "sha512-acBjXdRJ3A6Pb3tqnw9HZmyR3Fiol3aGxRCK1x3d+6CDAMjl7I649wpSd+yNURCjbOUGu9tqtLKnTGxmK6CyGw==", + "dependencies": [ + "undici-types" + ] + }, + "ansi-escapes@6.2.1": { + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==" + }, + "ansi-regex@5.0.1": { + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-regex@6.1.0": { + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==" + }, + "ansi-styles@4.3.0": { + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dependencies": [ + "color-convert" + ] + }, + "ansi-styles@6.2.1": { + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==" + }, + "aproba@2.0.0": { + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==" + }, + "are-we-there-yet@3.0.1": { + "integrity": "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg==", + "dependencies": [ + "delegates", + "readable-stream" + ] + }, + "async-retry@1.3.3": { + "integrity": "sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==", + "dependencies": [ + "retry@0.13.1" + ] + }, + "asynckit@0.4.0": { + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "axios@1.8.1": { + "integrity": "sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==", + "dependencies": [ + "follow-redirects", + "form-data", + "proxy-from-env" + ] + }, + "before-after-hook@3.0.2": { + "integrity": "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A==" + }, + "bottleneck@2.19.5": { + "integrity": "sha512-VHiNCbI1lKdl44tGrhNfU3lup0Tj/ZBMJB5/2ZbNXRCPuRCO7ed2mgcK4r17y+KB2EfuYuRaVlwNbAeaWGSpbw==" + }, + "bytes@3.1.2": { + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" + }, + "call-bind-apply-helpers@1.0.2": { + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": [ + "es-errors", + "function-bind" + ] + }, + "chalk@5.4.1": { + "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==" + }, + "chmodrp@1.0.2": { + "integrity": "sha512-TdngOlFV1FLTzU0o1w8MB6/BFywhtLC0SzRTGJU7T9lmdjlCWeMRt1iVo0Ki+ldwNk0BqNiKoc8xpLZEQ8mY1w==" + }, + "chownr@2.0.0": { + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==" + }, + "ci-info@4.1.0": { + "integrity": "sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==" + }, + "cli-cursor@5.0.0": { + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dependencies": [ + "restore-cursor" + ] + }, + "cli-spinners@2.9.2": { + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==" + }, + "cliui@8.0.1": { + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dependencies": [ + "string-width@4.2.3", + "strip-ansi@6.0.1", + "wrap-ansi" + ] + }, + "cmake-js@7.3.0": { + "integrity": "sha512-dXs2zq9WxrV87bpJ+WbnGKv8WUBXDw8blNiwNHoRe/it+ptscxhQHKB1SJXa1w+kocLMeP28Tk4/eTCezg4o+w==", + "dependencies": [ + "axios", + "debug", + "fs-extra", + "lodash.isplainobject", + "memory-stream", + "node-api-headers", + "npmlog", + "rc", + "semver", + "tar", + "url-join", + "which@2.0.2", + "yargs" + ] + }, + "color-convert@2.0.1": { + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": [ + "color-name" + ] + }, + "color-name@1.1.4": { + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "color-support@1.1.3": { + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + }, + "combined-stream@1.0.8": { + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": [ + "delayed-stream" + ] + }, + "commander@10.0.1": { + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==" + }, + "console-control-strings@1.1.0": { + "integrity": "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==" + }, + "cross-env@7.0.3": { + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dependencies": [ + "cross-spawn" + ] + }, + "cross-spawn@7.0.6": { + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dependencies": [ + "path-key", + "shebang-command", + "which@2.0.2" + ] + }, + "debug@4.4.0": { + "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "dependencies": [ + "ms" + ] + }, + "deep-extend@0.6.0": { + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "delayed-stream@1.0.0": { + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" + }, + "delegates@1.0.0": { + "integrity": "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==" + }, + "dunder-proto@1.0.1": { + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": [ + "call-bind-apply-helpers", + "es-errors", + "gopd" + ] + }, + "emoji-regex@10.4.0": { + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==" + }, + "emoji-regex@8.0.0": { + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "env-var@7.5.0": { + "integrity": "sha512-mKZOzLRN0ETzau2W2QXefbFjo5EF4yWq28OyKb9ICdeNhHJlOE/pHHnz4hdYJ9cNZXcJHo5xN4OT4pzuSHSNvA==" + }, + "es-define-property@1.0.1": { + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==" + }, + "es-errors@1.3.0": { + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==" + }, + "es-object-atoms@1.1.1": { + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": [ + "es-errors" + ] + }, + "es-set-tostringtag@2.1.0": { + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": [ + "es-errors", + "get-intrinsic", + "has-tostringtag", + "hasown" + ] + }, + "escalade@3.2.0": { + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==" + }, + "eventemitter3@5.0.1": { + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==" + }, + "fast-content-type-parse@2.0.1": { + "integrity": "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q==" + }, + "filename-reserved-regex@3.0.0": { + "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==" + }, + "filenamify@6.0.0": { + "integrity": "sha512-vqIlNogKeyD3yzrm0yhRMQg8hOVwYcYRfjEoODd49iCprMn4HL85gK3HcykQE53EPIpX3HcAbGA5ELQv216dAQ==", + "dependencies": [ + "filename-reserved-regex" + ] + }, + "follow-redirects@1.15.9": { + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==" + }, + "form-data@4.0.2": { + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "dependencies": [ + "asynckit", + "combined-stream", + "es-set-tostringtag", + "mime-types" + ] + }, + "fs-extra@11.3.0": { + "integrity": "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew==", + "dependencies": [ + "graceful-fs", + "jsonfile", + "universalify" + ] + }, + "fs-minipass@2.1.0": { + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dependencies": [ + "minipass@3.3.6" + ] + }, + "function-bind@1.1.2": { + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==" + }, + "gauge@4.0.4": { + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dependencies": [ + "aproba", + "color-support", + "console-control-strings", + "has-unicode", + "signal-exit@3.0.7", + "string-width@4.2.3", + "strip-ansi@6.0.1", + "wide-align" + ] + }, + "get-caller-file@2.0.5": { + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-east-asian-width@1.3.0": { + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==" + }, + "get-intrinsic@1.3.0": { + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": [ + "call-bind-apply-helpers", + "es-define-property", + "es-errors", + "es-object-atoms", + "function-bind", + "get-proto", + "gopd", + "has-symbols", + "hasown", + "math-intrinsics" + ] + }, + "get-proto@1.0.1": { + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": [ + "dunder-proto", + "es-object-atoms" + ] + }, + "gopd@1.2.0": { + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==" + }, + "graceful-fs@4.2.11": { + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==" + }, + "has-symbols@1.1.0": { + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==" + }, + "has-tostringtag@1.0.2": { + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": [ + "has-symbols" + ] + }, + "has-unicode@2.0.1": { + "integrity": "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==" + }, + "hasown@2.0.2": { + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": [ + "function-bind" + ] + }, + "ignore@7.0.3": { + "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==" + }, + "inherits@2.0.4": { + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + }, + "ini@1.3.8": { + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==" + }, + "ipull@3.9.2": { + "integrity": "sha512-YbCDsqcf0ytc3b8304ygBlvRtKJTvyygkQX2xcmPkih6vdVKbRw13pDdtSR+vEqLql3owyuPj9m6iT6IfwFaCg==", + "dependencies": [ + "@reflink/reflink", + "@tinyhttp/content-disposition", + "async-retry", + "chalk", + "ci-info", + "cli-spinners", + "commander", + "eventemitter3", + "filenamify", + "fs-extra", + "is-unicode-supported@2.1.0", + "lifecycle-utils@1.7.3", + "lodash.debounce", + "lowdb", + "pretty-bytes", + "pretty-ms@8.0.0", + "sleep-promise", + "slice-ansi", + "stdout-update", + "strip-ansi@7.1.0" + ] + }, + "is-fullwidth-code-point@3.0.0": { + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + }, + "is-fullwidth-code-point@5.0.0": { + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dependencies": [ + "get-east-asian-width" + ] + }, + "is-interactive@2.0.0": { + "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==" + }, + "is-unicode-supported@1.3.0": { + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==" + }, + "is-unicode-supported@2.1.0": { + "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==" + }, + "isexe@2.0.0": { + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "isexe@3.1.1": { + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==" + }, + "jmespath@0.16.0": { + "integrity": "sha512-9FzQjJ7MATs1tSpnco1K6ayiYE3figslrXA72G2HQ/n76RzvYlofyi5QM+iX4YRs/pu3yzxlVQSST23+dMDknw==" + }, + "jsonfile@6.1.0": { + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": [ + "graceful-fs", + "universalify" + ] + }, + "lifecycle-utils@1.7.3": { + "integrity": "sha512-T7zs7J6/sgsqwVyG34Sfo5LTQmlPmmqaUe3yBhdF8nq24RtR/HtbkNZRhNbr9BEaKySdSgH+P9H5U9X+p0WjXw==" + }, + "lifecycle-utils@2.0.0": { + "integrity": "sha512-KIkV6NeD2n0jZnO+fdIGKI5Or7alyhb6UTFzeaqf6EnE5y3pdK821+kd7yOMBUL/sPYhHU5ny74J0QKslLikGw==" + }, + "lodash-es@4.17.21": { + "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" + }, + "lodash.debounce@4.0.8": { + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==" + }, + "lodash.isplainobject@4.0.6": { + "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==" + }, + "log-symbols@6.0.0": { + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dependencies": [ + "chalk", + "is-unicode-supported@1.3.0" + ] + }, + "log-symbols@7.0.0": { + "integrity": "sha512-zrc91EDk2M+2AXo/9BTvK91pqb7qrPg2nX/Hy+u8a5qQlbaOflCKO+6SqgZ+M+xUFxGdKTgwnGiL96b1W3ikRA==", + "dependencies": [ + "is-unicode-supported@2.1.0", + "yoctocolors" + ] + }, + "lowdb@7.0.1": { + "integrity": "sha512-neJAj8GwF0e8EpycYIDFqEPcx9Qz4GUho20jWFR7YiFeXzF1YMLdxB36PypcTSPMA+4+LvgyMacYhlr18Zlymw==", + "dependencies": [ + "steno" + ] + }, + "math-intrinsics@1.1.0": { + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==" + }, + "memory-stream@1.0.0": { + "integrity": "sha512-Wm13VcsPIMdG96dzILfij09PvuS3APtcKNh7M28FsCA/w6+1mjR7hhPmfFNoilX9xU7wTdhsH5lJAm6XNzdtww==", + "dependencies": [ + "readable-stream" + ] + }, + "mime-db@1.52.0": { + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" + }, + "mime-types@2.1.35": { + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": [ + "mime-db" + ] + }, + "mimic-function@5.0.1": { + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==" + }, + "minimist@1.2.8": { + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==" + }, + "minipass@3.3.6": { + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dependencies": [ + "yallist" + ] + }, + "minipass@5.0.0": { + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==" + }, + "minizlib@2.1.2": { + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dependencies": [ + "minipass@3.3.6", + "yallist" + ] + }, + "mkdirp@1.0.4": { + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==" + }, + "ms@2.1.3": { + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" + }, + "nanoid@5.1.2": { + "integrity": "sha512-b+CiXQCNMUGe0Ri64S9SXFcP9hogjAJ2Rd6GdVxhPLRm7mhGaM7VgOvCAJ1ZshfHbqVDI3uqTI5C8/GaKuLI7g==" + }, + "node-addon-api@8.3.1": { + "integrity": "sha512-lytcDEdxKjGJPTLEfW4mYMigRezMlyJY8W4wxJK8zE533Jlb8L8dRuObJFWg2P+AuOIxoCgKF+2Oq4d4Zd0OUA==" + }, + "node-api-headers@1.5.0": { + "integrity": "sha512-Yi/FgnN8IU/Cd6KeLxyHkylBUvDTsSScT0Tna2zTrz8klmc8qF2ppj6Q1LHsmOueJWhigQwR4cO2p0XBGW5IaQ==" + }, + "node-llama-cpp@3.6.0": { + "integrity": "sha512-SzjsZLuG2pQPPkgMniTgK4sCcslA6ion5L55L8qeGnIb0cAhzVDbJ0Lxl5NhuTMm8KkxVZXF2yTihyulPMSLhw==", + "dependencies": [ + "@huggingface/jinja", + "@node-llama-cpp/linux-arm64", + "@node-llama-cpp/linux-armv7l", + "@node-llama-cpp/linux-x64", + "@node-llama-cpp/linux-x64-cuda", + "@node-llama-cpp/linux-x64-vulkan", + "@node-llama-cpp/mac-arm64-metal", + "@node-llama-cpp/mac-x64", + "@node-llama-cpp/win-arm64", + "@node-llama-cpp/win-x64", + "@node-llama-cpp/win-x64-cuda", + "@node-llama-cpp/win-x64-vulkan", + "async-retry", + "bytes", + "chalk", + "chmodrp", + "cmake-js", + "cross-env", + "cross-spawn", + "env-var", + "filenamify", + "fs-extra", + "ignore", + "ipull", + "is-unicode-supported@2.1.0", + "lifecycle-utils@2.0.0", + "log-symbols@7.0.0", + "nanoid", + "node-addon-api", + "octokit", + "ora", + "pretty-ms@9.2.0", + "proper-lockfile", + "semver", + "simple-git", + "slice-ansi", + "stdout-update", + "strip-ansi@7.1.0", + "validate-npm-package-name", + "which@5.0.0", + "yargs" + ] + }, + "npmlog@6.0.2": { + "integrity": "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg==", + "dependencies": [ + "are-we-there-yet", + "console-control-strings", + "gauge", + "set-blocking" + ] + }, + "octokit@4.1.0_@octokit+core@6.1.3": { + "integrity": "sha512-/UrQAOSvkc+lUUWKNzy4ByAgYU9KpFzZQt8DnC962YmQuDiZb1SNJ90YukCCK5aMzKqqCA+z1kkAlmzYvdYKag==", + "dependencies": [ + "@octokit/app", + "@octokit/core", + "@octokit/oauth-app", + "@octokit/plugin-paginate-graphql", + "@octokit/plugin-paginate-rest", + "@octokit/plugin-rest-endpoint-methods", + "@octokit/plugin-retry", + "@octokit/plugin-throttling", + "@octokit/request-error", + "@octokit/types" + ] + }, + "onetime@7.0.0": { + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dependencies": [ + "mimic-function" + ] + }, + "ora@8.2.0": { + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "dependencies": [ + "chalk", + "cli-cursor", + "cli-spinners", + "is-interactive", + "is-unicode-supported@2.1.0", + "log-symbols@6.0.0", + "stdin-discarder", + "string-width@7.2.0", + "strip-ansi@7.1.0" + ] + }, + "parse-ms@3.0.0": { + "integrity": "sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==" + }, + "parse-ms@4.0.0": { + "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==" + }, + "path-key@3.1.1": { + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "pretty-bytes@6.1.1": { + "integrity": "sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ==" + }, + "pretty-ms@8.0.0": { + "integrity": "sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==", + "dependencies": [ + "parse-ms@3.0.0" + ] + }, + "pretty-ms@9.2.0": { + "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==", + "dependencies": [ + "parse-ms@4.0.0" + ] + }, + "proper-lockfile@4.1.2": { + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dependencies": [ + "graceful-fs", + "retry@0.12.0", + "signal-exit@3.0.7" + ] + }, + "proxy-from-env@1.1.0": { + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "rc@1.2.8": { + "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", + "dependencies": [ + "deep-extend", + "ini", + "minimist", + "strip-json-comments" + ] + }, + "readable-stream@3.6.2": { + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dependencies": [ + "inherits", + "string_decoder", + "util-deprecate" + ] + }, + "require-directory@2.1.1": { + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==" + }, + "restore-cursor@5.1.0": { + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dependencies": [ + "onetime", + "signal-exit@4.1.0" + ] + }, + "retry@0.12.0": { + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==" + }, + "retry@0.13.1": { + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==" + }, + "safe-buffer@5.2.1": { + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" + }, + "semver@7.7.1": { + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==" + }, + "set-blocking@2.0.0": { + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==" + }, + "shebang-command@2.0.0": { + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": [ + "shebang-regex" + ] + }, + "shebang-regex@3.0.0": { + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" + }, + "signal-exit@3.0.7": { + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==" + }, + "signal-exit@4.1.0": { + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==" + }, + "simple-git@3.27.0": { + "integrity": "sha512-ivHoFS9Yi9GY49ogc6/YAi3Fl9ROnF4VyubNylgCkA+RVqLaKWnDSzXOVzya8csELIaWaYNutsEuAhZrtOjozA==", + "dependencies": [ + "@kwsites/file-exists", + "@kwsites/promise-deferred", + "debug" + ] + }, + "sleep-promise@9.1.0": { + "integrity": "sha512-UHYzVpz9Xn8b+jikYSD6bqvf754xL2uBUzDFwiU6NcdZeifPr6UfgU43xpkPu67VMS88+TI2PSI7Eohgqf2fKA==" + }, + "slice-ansi@7.1.0": { + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dependencies": [ + "ansi-styles@6.2.1", + "is-fullwidth-code-point@5.0.0" + ] + }, + "stdin-discarder@0.2.2": { + "integrity": "sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==" + }, + "stdout-update@4.0.1": { + "integrity": "sha512-wiS21Jthlvl1to+oorePvcyrIkiG/6M3D3VTmDUlJm7Cy6SbFhKkAvX+YBuHLxck/tO3mrdpC/cNesigQc3+UQ==", + "dependencies": [ + "ansi-escapes", + "ansi-styles@6.2.1", + "string-width@7.2.0", + "strip-ansi@7.1.0" + ] + }, + "steno@4.0.2": { + "integrity": "sha512-yhPIQXjrlt1xv7dyPQg2P17URmXbuM5pdGkpiMB3RenprfiBlvK415Lctfe0eshk90oA7/tNq7WEiMK8RSP39A==" + }, + "string-width@4.2.3": { + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": [ + "emoji-regex@8.0.0", + "is-fullwidth-code-point@3.0.0", + "strip-ansi@6.0.1" + ] + }, + "string-width@7.2.0": { + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dependencies": [ + "emoji-regex@10.4.0", + "get-east-asian-width", + "strip-ansi@7.1.0" + ] + }, + "string_decoder@1.3.0": { + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dependencies": [ + "safe-buffer" + ] + }, + "strip-ansi@6.0.1": { + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": [ + "ansi-regex@5.0.1" + ] + }, + "strip-ansi@7.1.0": { + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dependencies": [ + "ansi-regex@6.1.0" + ] + }, + "strip-json-comments@2.0.1": { + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==" + }, + "tar@6.2.1": { + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dependencies": [ + "chownr", + "fs-minipass", + "minipass@5.0.0", + "minizlib", + "mkdirp", + "yallist" + ] + }, + "toad-cache@3.7.0": { + "integrity": "sha512-/m8M+2BJUpoJdgAHoG+baCwBT+tf2VraSfkBgl0Y00qIWt41DJ8R5B8nsEw0I58YwF5IZH6z24/2TobDKnqSWw==" + }, + "undici-types@6.20.0": { + "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==" + }, + "universal-github-app-jwt@2.2.0": { + "integrity": "sha512-G5o6f95b5BggDGuUfKDApKaCgNYy2x7OdHY0zSMF081O0EJobw+1130VONhrA7ezGSV2FNOGyM+KQpQZAr9bIQ==" + }, + "universal-user-agent@7.0.2": { + "integrity": "sha512-0JCqzSKnStlRRQfCdowvqy3cy0Dvtlb8xecj/H8JFZuCze4rwjPZQOgvFvn0Ws/usCHQFGpyr+pB9adaGwXn4Q==" + }, + "universalify@2.0.1": { + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==" + }, + "url-join@4.0.1": { + "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==" + }, + "util-deprecate@1.0.2": { + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" + }, + "validate-npm-package-name@6.0.0": { + "integrity": "sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg==" + }, + "which@2.0.2": { + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dependencies": [ + "isexe@2.0.0" + ] + }, + "which@5.0.0": { + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dependencies": [ + "isexe@3.1.1" + ] + }, + "wide-align@1.1.5": { + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dependencies": [ + "string-width@4.2.3" + ] + }, + "wrap-ansi@7.0.0": { + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dependencies": [ + "ansi-styles@4.3.0", + "string-width@4.2.3", + "strip-ansi@6.0.1" + ] + }, + "y18n@5.0.8": { + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==" + }, + "yallist@4.0.0": { + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yargs-parser@21.1.1": { + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==" + }, + "yargs@17.7.2": { + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dependencies": [ + "cliui", + "escalade", + "get-caller-file", + "require-directory", + "string-width@4.2.3", + "y18n", + "yargs-parser" + ] + }, + "yoctocolors@2.1.1": { + "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==" + } + }, + "redirects": { + "https://esm.sh/@octokit/app@^15.1.2?target=denonext": "https://esm.sh/@octokit/app@15.1.2?target=denonext", + "https://esm.sh/@octokit/auth-app@^7.1.4?target=denonext": "https://esm.sh/@octokit/auth-app@7.1.4?target=denonext", + "https://esm.sh/@octokit/auth-oauth-app@^8.1.2?target=denonext": "https://esm.sh/@octokit/auth-oauth-app@8.1.2?target=denonext", + "https://esm.sh/@octokit/auth-oauth-device@^7.1.2?target=denonext": "https://esm.sh/@octokit/auth-oauth-device@7.1.2?target=denonext", + "https://esm.sh/@octokit/auth-oauth-user@^5.1.2?target=denonext": "https://esm.sh/@octokit/auth-oauth-user@5.1.2?target=denonext", + "https://esm.sh/@octokit/auth-token@^5.0.0?target=denonext": "https://esm.sh/@octokit/auth-token@5.1.2?target=denonext", + "https://esm.sh/@octokit/auth-unauthenticated@^6.1.1?target=denonext": "https://esm.sh/@octokit/auth-unauthenticated@6.1.1?target=denonext", + "https://esm.sh/@octokit/core@^6.1.3?target=denonext": "https://esm.sh/@octokit/core@6.1.3?target=denonext", + "https://esm.sh/@octokit/endpoint@^10.0.0?target=denonext": "https://esm.sh/@octokit/endpoint@10.1.2?target=denonext", + "https://esm.sh/@octokit/graphql@^8.1.2?target=denonext": "https://esm.sh/@octokit/graphql@8.2.0?target=denonext", + "https://esm.sh/@octokit/oauth-app@^7.1.4?target=denonext": "https://esm.sh/@octokit/oauth-app@7.1.5?target=denonext", + "https://esm.sh/@octokit/oauth-app@^7.1.5?target=denonext": "https://esm.sh/@octokit/oauth-app@7.1.5?target=denonext", + "https://esm.sh/@octokit/oauth-authorization-url@^7.0.0?target=denonext": "https://esm.sh/@octokit/oauth-authorization-url@7.1.1?target=denonext", + "https://esm.sh/@octokit/oauth-methods@^5.1.2?target=denonext": "https://esm.sh/@octokit/oauth-methods@5.1.3?target=denonext", + "https://esm.sh/@octokit/oauth-methods@^5.1.3?target=denonext": "https://esm.sh/@octokit/oauth-methods@5.1.3?target=denonext", + "https://esm.sh/@octokit/plugin-paginate-graphql@^5.2.4?target=denonext": "https://esm.sh/@octokit/plugin-paginate-graphql@5.2.4?target=denonext", + "https://esm.sh/@octokit/plugin-paginate-rest@^11.3.6?target=denonext": "https://esm.sh/@octokit/plugin-paginate-rest@11.4.0?target=denonext", + "https://esm.sh/@octokit/plugin-paginate-rest@^11.4.0?target=denonext": "https://esm.sh/@octokit/plugin-paginate-rest@11.4.0?target=denonext", + "https://esm.sh/@octokit/plugin-rest-endpoint-methods@^13.3.0?target=denonext": "https://esm.sh/@octokit/plugin-rest-endpoint-methods@13.3.0?target=denonext", + "https://esm.sh/@octokit/plugin-retry@^7.1.3?target=denonext": "https://esm.sh/@octokit/plugin-retry@7.1.3?target=denonext", + "https://esm.sh/@octokit/plugin-throttling@^9.4.0?target=denonext": "https://esm.sh/@octokit/plugin-throttling@9.4.0?target=denonext", + "https://esm.sh/@octokit/request-error@^6.0.1?target=denonext": "https://esm.sh/@octokit/request-error@6.1.6?target=denonext", + "https://esm.sh/@octokit/request-error@^6.1.6?target=denonext": "https://esm.sh/@octokit/request-error@6.1.6?target=denonext", + "https://esm.sh/@octokit/request@^9.1.4?target=denonext": "https://esm.sh/@octokit/request@9.2.0?target=denonext", + "https://esm.sh/@octokit/webhooks-methods@^5.0.0?target=denonext": "https://esm.sh/@octokit/webhooks-methods@5.1.0?target=denonext", + "https://esm.sh/@octokit/webhooks@^13.4.2?target=denonext": "https://esm.sh/@octokit/webhooks@13.5.0?target=denonext", + "https://esm.sh/before-after-hook@^3.0.2?target=denonext": "https://esm.sh/before-after-hook@3.0.2?target=denonext", + "https://esm.sh/bottleneck@^2.15.3/light?target=denonext": "https://esm.sh/bottleneck@2.19.5/light?target=denonext", + "https://esm.sh/fast-content-type-parse@^2.0.0?target=denonext": "https://esm.sh/fast-content-type-parse@2.0.1?target=denonext", + "https://esm.sh/octokit?dts": "https://esm.sh/octokit@4.1.0?dts", + "https://esm.sh/toad-cache@^3.7.0?target=denonext": "https://esm.sh/toad-cache@3.7.0?target=denonext", + "https://esm.sh/universal-github-app-jwt@^2.2.0?target=denonext": "https://esm.sh/universal-github-app-jwt@2.2.0?target=denonext", + "https://esm.sh/universal-user-agent@^7.0.0?target=denonext": "https://esm.sh/universal-user-agent@7.0.2?target=denonext", + "https://esm.sh/universal-user-agent@^7.0.2?target=denonext": "https://esm.sh/universal-user-agent@7.0.2?target=denonext" + }, + "remote": { + "https://esm.sh/@octokit/app@15.1.2/denonext/app.mjs": "21c4fdfecfc4540b17c21b3c0cf1e0a5c7eb55bab034978af33d7dd7a06ab4ab", + "https://esm.sh/@octokit/app@15.1.2?target=denonext": "51ad31b108532bc255a43647574518580d5e95d5ad7a968df7bb477b71b59e79", + "https://esm.sh/@octokit/auth-app@7.1.4/denonext/auth-app.mjs": "c2c8bc96d4760e5a0af7535c1aa669ebc8b490764b575d8113632515f11760c6", + "https://esm.sh/@octokit/auth-app@7.1.4?target=denonext": "a4632ee3c6af2cfde6e6249c13d5d7706575649ac570389f6117bd37eab0b523", + "https://esm.sh/@octokit/auth-oauth-app@8.1.2/denonext/auth-oauth-app.mjs": "1803a9d024ec1d9b53c9fdc5d386d05990ee6b6715d2ad79619f8452fd9d5d13", + "https://esm.sh/@octokit/auth-oauth-app@8.1.2?target=denonext": "8c48ca11c1b9e2d08c56555fa61b13cb5050366b3e0412ceb19a1e314f355015", + "https://esm.sh/@octokit/auth-oauth-device@7.1.2/denonext/auth-oauth-device.mjs": "24ac890f2a933a5532ea37f9e94b1185c24dfd163339300fce36a132f2ccd6d3", + "https://esm.sh/@octokit/auth-oauth-device@7.1.2?target=denonext": "f2d03bf3a4208a0cabd8e4b85c98d633f857678e811bf6de4429d1d9439da0eb", + "https://esm.sh/@octokit/auth-oauth-user@5.1.2/denonext/auth-oauth-user.mjs": "4f1ce58465e50c7f79d58794976da1853f9785bf5434b19d81a50c400a9ed858", + "https://esm.sh/@octokit/auth-oauth-user@5.1.2?target=denonext": "54d806f7a2b19086b880d27cbbf863985c9f9f26914c031a99ad849a85cdbcbe", + "https://esm.sh/@octokit/auth-token@5.1.2/denonext/auth-token.mjs": "360feb2cb940bfa2e20ba6e5b7c366b207e7b8cb3a2ff983f3d33b19087cdc50", + "https://esm.sh/@octokit/auth-token@5.1.2?target=denonext": "0e5dc846d0c00da36580f08e0d4115526daf6256acf07fabedc06716dfbf72c9", + "https://esm.sh/@octokit/auth-unauthenticated@6.1.1/denonext/auth-unauthenticated.mjs": "1cd86628013b6444922993cd740ed0a327dd220ac465595ccad05de8fb2f80f8", + "https://esm.sh/@octokit/auth-unauthenticated@6.1.1?target=denonext": "a00a18f165e48e1d98e6d5e4266aee4a0bde051b7342c54ebd838d2547538ae4", + "https://esm.sh/@octokit/core@6.1.3/denonext/core.mjs": "27711bac5522d962bca6513035a3ab2e55c001f49e050175bb67bbedd4049535", + "https://esm.sh/@octokit/core@6.1.3?target=denonext": "48e4022a4e8ae6df3eec7b9028bfc452b113f1746c81737861b06d44c6791f03", + "https://esm.sh/@octokit/endpoint@10.1.2/denonext/endpoint.mjs": "10aa9cb55330d89ef4392f710c7f1132b30d3018d1a548af90d50837ad8d8640", + "https://esm.sh/@octokit/endpoint@10.1.2?target=denonext": "e44433015f71eb9ebf694f7e66880a96505b503e0d6f172c63267259cf7810e7", + "https://esm.sh/@octokit/graphql@8.2.0/denonext/graphql.mjs": "a26719a9e0adfc72773caaca5857a67ddf54b7824efd0f4585c4a14bba66a566", + "https://esm.sh/@octokit/graphql@8.2.0?target=denonext": "f1f248a1461a1c8a230e0d45dd6979a21205c29941ee790ef9d779da05259305", + "https://esm.sh/@octokit/oauth-app@7.1.5/denonext/oauth-app.mjs": "946907b1ce34610a973305985d4861e2377b83cb463dcd1724ffb917af8188c9", + "https://esm.sh/@octokit/oauth-app@7.1.5?target=denonext": "373b5044d98bccffa8aa0dc180c9f013a5e6ae95eba0b4481feb7204458d4c1b", + "https://esm.sh/@octokit/oauth-authorization-url@7.1.1/denonext/oauth-authorization-url.mjs": "209de15074485c12e6bffaed0f33d857c789df4a577b19ddbd78caa9646b77dc", + "https://esm.sh/@octokit/oauth-authorization-url@7.1.1?target=denonext": "fdaed10ede57c5e5a3ae67b487331336916d5401d366bed1425515e104b95de1", + "https://esm.sh/@octokit/oauth-methods@5.1.3/denonext/oauth-methods.mjs": "9043d6ed33f54207cab9966eb6f984f87e62c5c4ed3e019aa3b28d02ea738eac", + "https://esm.sh/@octokit/oauth-methods@5.1.3?target=denonext": "d185bf52b6cd01f4d13fcf25ca7bce03e8534b06835c0ad6783366c6676311a6", + "https://esm.sh/@octokit/plugin-paginate-graphql@5.2.4/denonext/plugin-paginate-graphql.mjs": "a2b0869cb5eb1e14516d1d2ba227e2b968afe05ed9b3895f005ac196e7b5c5a1", + "https://esm.sh/@octokit/plugin-paginate-graphql@5.2.4?target=denonext": "1512bade9daddb1ffe8fc46693db5dd3df429d51264e6848e3de3ea0cd16bc61", + "https://esm.sh/@octokit/plugin-paginate-rest@11.4.0/denonext/plugin-paginate-rest.mjs": "3bb02e7f514dee857103ceb9d922621bed80115bfe0fb1d7197a7a7cd44cfa6f", + "https://esm.sh/@octokit/plugin-paginate-rest@11.4.0?target=denonext": "b4e0d949bdd6a34257cddde0262ca67e82a158aba5bbfeb00f54e6939770c17b", + "https://esm.sh/@octokit/plugin-rest-endpoint-methods@13.3.0/denonext/plugin-rest-endpoint-methods.mjs": "8254da50e1460596143fb2d49314f97fc0b9bae60d0259594c3a6b98bca5c266", + "https://esm.sh/@octokit/plugin-rest-endpoint-methods@13.3.0?target=denonext": "b54fb93130dea1a56de1d434e6c900793ab05281c0086129cbd60411a07039bd", + "https://esm.sh/@octokit/plugin-retry@7.1.3/denonext/plugin-retry.mjs": "b55a731984d30e256309ef0ad6eca64d34ea4cc61c747f711b7c45b0e4e1b086", + "https://esm.sh/@octokit/plugin-retry@7.1.3?target=denonext": "5f0e94e59f4a593ef911c8c10796a73d9ef5289505c129a647f90fdf3405d833", + "https://esm.sh/@octokit/plugin-throttling@9.4.0/denonext/plugin-throttling.mjs": "50c4a67edc2bba79d81f5ea8966175a3acffbffe3403b5815da172e0c12ab686", + "https://esm.sh/@octokit/plugin-throttling@9.4.0?target=denonext": "d40a7eb26c4897bb17e4cddd341a25f85ea0607798d5ee3e48014693f07e98b5", + "https://esm.sh/@octokit/request-error@6.1.6/denonext/request-error.mjs": "a3bb74761fbdc7b1fbc406f0a2ace10f82f64706ffc9596a90badef765414c5e", + "https://esm.sh/@octokit/request-error@6.1.6?target=denonext": "bfebd513aea83d3df72e2f0b70f9e2dcd7aafed463c095f7388ca3dd10621e7d", + "https://esm.sh/@octokit/request@9.2.0/denonext/request.mjs": "662411deed3a6c54a960c802b24795bc8ce65649e0a941ba848fa6f68e7d0070", + "https://esm.sh/@octokit/request@9.2.0?target=denonext": "550f4054c2e0eba7174dd21aa9117e6934f3bb3d3b3c43f6d4a1471cef3a04d9", + "https://esm.sh/@octokit/webhooks-methods@5.1.0/denonext/webhooks-methods.mjs": "fdaefa3e104afcf645fb3a35a1bb557c31e7d069342f1518df72fd5662c28932", + "https://esm.sh/@octokit/webhooks-methods@5.1.0?target=denonext": "5a77eef071b9134be9a6ed9358b553195aae275b36e7b7e7c146f0b90d1baa92", + "https://esm.sh/@octokit/webhooks@13.5.0/denonext/webhooks.mjs": "b94ff89a92ac22f1cd0307314d976fa5a34a0a731d7e79bf8962201fb3ecd013", + "https://esm.sh/@octokit/webhooks@13.5.0?target=denonext": "6e3bc47e2034b2421d1c5e4cf652aa0a330c887aa69c6bf704923eda42722ae7", + "https://esm.sh/before-after-hook@3.0.2/denonext/before-after-hook.mjs": "1a862839e15e4816de946c11023cbec3cb1d276e3a86073adfaac9dca6871aca", + "https://esm.sh/before-after-hook@3.0.2?target=denonext": "923592fc40b4609eac335800f88c890d81c5f5f12e0b22fd8fd0646313c634f7", + "https://esm.sh/bottleneck@2.19.5/denonext/light.mjs": "943b72d08b33e678a4f64bf2ce9a0468f9356ee65092af9c893fa25d3be6518b", + "https://esm.sh/bottleneck@2.19.5/light?target=denonext": "c53ee9007926e5a49e291e0a0f2e1113735d65271a33eb609ac9ad309def4878", + "https://esm.sh/fast-content-type-parse@2.0.1/denonext/fast-content-type-parse.mjs": "436d0ff6ce4508efcb9023892d25cc9d7eb321e9321a0d3aaf870300dc2e8578", + "https://esm.sh/fast-content-type-parse@2.0.1?target=denonext": "7170ebd0186887d73afc67050a28e5350171e5e842e82a10309e829eabdf138a", + "https://esm.sh/octokit@4.1.0/denonext/octokit.mjs": "0e522b2239c7f7d673022e81dd55b2dcb6ce42b905f1cfc82a5dfbbd2c24af28", + "https://esm.sh/octokit@4.1.0?dts": "094de1c868d2aaa8be65d7135d3feeee8006a5e2d76683f5bfcc32243557cdfc", + "https://esm.sh/toad-cache@3.7.0/denonext/toad-cache.mjs": "63b78525dcc99d8f736de244e46b306b2b5f6c72db75bf1d230230d46a06ab37", + "https://esm.sh/toad-cache@3.7.0?target=denonext": "e17c2f2729b3268a6ecb412b975002ebaa66894c2e5e0a657a38d1176a1f02d4", + "https://esm.sh/universal-github-app-jwt@2.2.0/denonext/universal-github-app-jwt.mjs": "c7cb04f796b43f163b1bcaf2b85c742d11ae724ae5ea82dbe517617c33bd0467", + "https://esm.sh/universal-github-app-jwt@2.2.0?target=denonext": "75d402511284eb488f2f2c0f39cc5122ec91c3de1a18eebe1360f2935a0e577a", + "https://esm.sh/universal-user-agent@7.0.2/denonext/universal-user-agent.mjs": "c5370728870841e1061776d12f5776929bb04945b0f8d5e4251207eab57d35ea", + "https://esm.sh/universal-user-agent@7.0.2?target=denonext": "1c7589a3ed835be8bf13e6c78c7d507af65b7945b92edbf3ad25428e60e072f4" + }, + "workspace": { + "dependencies": [ + "jsr:@eta-dev/eta@^3.5.0", + "jsr:@logtape/logtape@~0.8.1", + "jsr:@std/assert@1", + "jsr:@std/cli@^1.0.12", + "jsr:@std/collections@^1.0.10", + "jsr:@std/dotenv@~0.225.3", + "jsr:@std/path@^1.0.8", + "npm:@types/node@^22.13.9", + "npm:jmespath@0.16", + "npm:lodash-es@^4.17.21", + "npm:node-llama-cpp@^3.6.0", + "npm:octokit@^4.1.0" + ] + } +} diff --git a/src/msg-handlers/base-handler.ts b/src/msg-handlers/base-handler.ts new file mode 100644 index 0000000..e4fa0b1 --- /dev/null +++ b/src/msg-handlers/base-handler.ts @@ -0,0 +1,41 @@ +import { EventEmitter } from "node:events" +import {Bot, Message, User} from "../snek/snek-socket.ts" +import { trim } from "npm:lodash-es" + +export abstract class BaseHandler extends EventEmitter { + prefix = "msg-handler" + user: User|null = null + + constructor(prefix: string) { + super() + this.prefix = prefix.toLowerCase() + } + + async bind(bot: Bot) { + this.user = await bot.user + bot.on("message", async (message) => { + try { + if (await this.isMatch(message)) { + try { + await this.handleMessage(message, bot) + } catch (e) { + message.reply("An error occurred while handling your message") + console.error("Error handling message", e) + } + } + } catch (e) { + console.error("Error checking message", e) + } + }) + } + + async isMatch(message: Message): Promise<boolean> { + return message.userUID !== this.user?.uid && + trim(message?.message, ' `').toLowerCase().startsWith(this.prefix) + } + + abstract handleMessage( + message: Message, + bot: Bot, + ): Promise<void> | void +} diff --git a/src/msg-handlers/img-gen-handler.ts b/src/msg-handlers/img-gen-handler.ts new file mode 100644 index 0000000..03b07b8 --- /dev/null +++ b/src/msg-handlers/img-gen-handler.ts @@ -0,0 +1,187 @@ +import {Bot, Message} from "../snek/snek-socket.ts" +import {BaseHandler} from "./base-handler.ts" +import {ImgGen} from "../util/img-gen.ts" +import {Eta} from "jsr:@eta-dev/eta" +import { getLogger } from "@logtape/logtape" +import * as path from "node:path" +import {randomUUID} from "node:crypto"; + +const TEMPLATES = new Eta({ views: path.join(Deno.cwd(), "templates/img-gen") }) + +const FORMATTING_WRAPPER = /^\s*`(?:``\w+)?(.*?)(?:``)?`\s*$/gs + +const logger = getLogger(["img-gen-handler"]) + +const parsePrompt = (prompt: string): Record<string, unknown> => { + try { + return JSON.parse(prompt) + } catch (e) { + prompt = prompt.replace(FORMATTING_WRAPPER, "$1") + return JSON.parse(prompt) + } +} + +export class ImgGenHandler extends BaseHandler { + #imageGenerator = new ImgGen() + #activeTemplate = "flux-dev.eta" + #templateVariables: Record<string, unknown> = { + steps: 20, + seed: 0, + cfg: 2, + sampler: "euler", + negativePrompt: "", + batchSize: 1, + width: 1024, + height: 1024, + } + + #subCommands = { + "prompt": this.prompt.bind(this), + "template": this.template.bind(this), + "variables": this.variables.bind(this), + } as Record<string, (command: string, message: Message, bot: Bot) => void> + + constructor() { + super("/img-gen") + } + + override async handleMessage(message: Message, bot: Bot) { + const newMessage = message.message.substring(this.prefix.length).trim() + if (!newMessage) { + message.reply( + "No command given, try one of: " + + Object.keys(this.#subCommands).join(", "), + ) + return + } + + const [[_, command, rest]] = newMessage.matchAll(/^(\w+)\s*(.*)$/gs) + + if (command in this.#subCommands) { + this.#subCommands[command]?.(rest.trim(), message, bot) + return + } + + message.reply( + "Invalid command, assuming prompt. Otherwise these are the correct ones: " + + Object.keys(this.#subCommands).join(", "), + ) + + await this.prompt(newMessage, message, bot) + } + + async prompt(command: string, message: Message, bot: Bot) { + if (!command) { + message.reply("No prompt given") + return + } + try { + logger.info("Generating image", { command, variables: this.#templateVariables, message }) + + const prompt = parsePrompt( + await TEMPLATES.renderAsync(this.#activeTemplate, { + ...this.#templateVariables, + randomSeed: ( + min: number = 0, + max: number = Number.MAX_SAFE_INTEGER, + ) => Math.floor(Math.random() * (max - min + 1)) + min, + prompt: command.replaceAll("\n", " "), + }), + ) + + message.reply("image generated called") + + const promptResults = await this.#imageGenerator.dispatchPrompt( + prompt, + ) + + const blob = promptResults.filter((result) => result instanceof Blob) + + if (blob.length === 0) { + console.log("Prompt Results: ", promptResults) + message.reply("Failed to generate image") + return + } + + const files = await Promise.all( + blob.map(async (blob) => + new File([(await blob.arrayBuffer()).slice(8)], `${randomUUID()}.png`) + ), + ) + + await bot.uploadFiles(message.channelUID, ...files) + } catch (e) { + console.error(e) + message.reply(`Failed to generate image: ${e.message}`) + } + } + + async template(command: string, message: Message, bot: Bot) { + if (!command) { + const templatePath = TEMPLATES.config.views + if (templatePath) { + const templateOptions = await Deno.readDir(templatePath) + let templateList = + `Current template: ${this.#activeTemplate}\n\nTemplates:\n` + for await (const template of templateOptions) { + templateList += ` - ${template.name}\n` + } + message.reply(templateList) + } else { + message.reply(`Current template: ${this.#activeTemplate}`) + return + } + return + } + + const [[_, template, rest]] = command.matchAll(/^(\S+)\s*(.*)$/gs) + + if (!template) { + message.reply("No template given") + return + } + + if (template.startsWith("@")) { + TEMPLATES.loadTemplate(template, rest, { async: true }) + this.#activeTemplate = template + message.reply(`Template set to ${template}`) + } else { + try { + Deno.readFileSync(TEMPLATES.resolvePath(template)) + this.#activeTemplate = template + message.reply(`Template set to ${template}`) + } catch (e) { + message.reply(`Failed to load template: ${e.message}`) + return + } + } + } + + variables(command: string, message: Message, bot: Bot) { + if (!command) { + let currentVariables = "Current Variables:\n\n```json\n" + currentVariables += JSON.stringify(this.#templateVariables, null, 2) + currentVariables += "\n```" + message.reply(currentVariables) + + return + } + + const [[_, variable, value]] = command.matchAll(/^(\S+)\s*(.*)$/gs) + + if (!variable) { + message.reply("No variable given") + return + } + + if (!value) { + message.reply( + `Variable ${variable} = ${this.#templateVariables[variable]}`, + ) + return + } + + this.#templateVariables[variable] = value + message.reply(`Variable set: ${variable} = ${value}`) + } +} diff --git a/src/msg-handlers/llama-handler.ts b/src/msg-handlers/llama-handler.ts new file mode 100644 index 0000000..7223df5 --- /dev/null +++ b/src/msg-handlers/llama-handler.ts @@ -0,0 +1,212 @@ +import {BaseHandler} from "./base-handler.ts" +import {Bot, Message} from "../snek/snek-socket.ts" +import {trim, trimStart} from "npm:lodash-es" +import { + ChatSessionModelFunctions, + ChatWrapper, + GeneralChatWrapper, + getLlama, + LLamaChatPromptOptions, + LlamaChatSession, + LlamaContext, + LlamaModel, + resolveChatWrapper, + Token, +} from "npm:node-llama-cpp" +import {getLogger} from "@logtape/logtape" +import {deepMerge} from "@std/collections/deep-merge" + +const llama = await getLlama() + +const textEncoder = new TextEncoder() + +function printSync(input: string | Uint8Array, to = Deno.stdout) { + let bytesWritten = 0 + const bytes = typeof input === "string" ? textEncoder.encode(input) : input + while (bytesWritten < bytes.length) { + bytesWritten += to.writeSync(bytes.subarray(bytesWritten)) + } +} +const logger = getLogger(["llama-gen-handler"]) + +const optionsGenerator = < + const Functions extends ChatSessionModelFunctions | undefined = undefined, + LLamaOptions = LLamaChatPromptOptions<Functions> +>( + model: LlamaModel, + debugOutput: boolean = true, + defaultTimeout = 5 * 60 * 1000, + options?: LLamaOptions, +): LLamaChatPromptOptions<Functions> => { + const manager = AbortSignal.timeout(defaultTimeout) + + const defaultOptions: LLamaChatPromptOptions<Functions> = { + repeatPenalty: { + lastTokens: 24, + penalty: 1.12, + penalizeNewLine: true, + frequencyPenalty: 0.02, + presencePenalty: 0.02, + punishTokensFilter: (tokens: Token[]) => { + return tokens.filter((token) => { + const text = model.detokenize([token]) + + // allow the model to repeat tokens + // that contain the word "better" + return !text.toLowerCase().includes("@") + // TODO: Exclude usernames + }) + }, + }, + temperature: 0.6, + + signal: manager, + stopOnAbortSignal: true, + } + + if (debugOutput) { + defaultOptions.onResponseChunk = (chunk) => { + const isThoughtSegment = chunk.type === "segment" && + chunk.segmentType === "thought" + + if ( + chunk.type === "segment" && chunk.segmentStartTime != null + ) { + printSync(` [segment start: ${chunk.segmentType}] `) + } + + printSync(chunk.text) + + if (chunk.type === "segment" && chunk.segmentEndTime != null) { + printSync(` [segment end: ${chunk.segmentType}] `) + } + } + } + + return deepMerge(defaultOptions, options) +} + +export class LLamaHandler extends BaseHandler { + joinMode = false + debugLogResponses = true + + systemPrompt: string + + #activeModel: string + + #model: LlamaModel | null = null + #context: LlamaContext | null = null + + #chatWrapper: ChatWrapper | null = null + + #session: LlamaChatSession | null = null + + constructor( + activeModel: string, + systemPrompt: string = "You are an AI chatbot.", + ) { + super("") + this.#activeModel = activeModel + this.systemPrompt = systemPrompt + } + + async calculateSystemPrompt(): Promise<string> { + return this.systemPrompt + } + + override async bind(bot: Bot): Promise<void> { + await super.bind(bot) + this.prefix = "@" + this.user?.username.toLowerCase() + + this.#model = await llama.loadModel({ + modelPath: this.#activeModel, + defaultContextFlashAttention: true, + }) + + this.#context = await this.#model.createContext({ + flashAttention: true, + }) + + logger.info("Model loaded", { + batchSize: this.#context.batchSize, + contextSize: this.#context.contextSize, + }) + console.log("Model loaded", { + batchSize: this.#context.batchSize, + contextSize: this.#context.contextSize, + }) + + this.#chatWrapper = //new Llama3ChatWrapper() + resolveChatWrapper({ + bosString: this.#model + .tokens + .bosString, + filename: this.#model + .filename, + fileInfo: this.#model + .fileInfo, + tokenizer: this.#model + .tokenizer, + }) ?? new GeneralChatWrapper() + + this.#session = new LlamaChatSession({ + contextSequence: this.#context.getSequence(), + chatWrapper: this.#chatWrapper, + systemPrompt: await this.calculateSystemPrompt(), + }) + + const channels = await bot.channels + + const channel = channels.find((v) => v.tag === "public") || channels[0] + + if (channel) { + await bot.sendMessage( + channel.uid, + await this.#session.prompt( + "Welcome to chat, greet everyone\n", + optionsGenerator(this.#model, this.debugLogResponses), + ), + ) + this.#session.resetChatHistory() + } + } + + override async isMatch(message: Message): Promise<boolean> { + return message.userUID !== this.user?.uid && (this.joinMode || + trim(message?.message, " `").toLowerCase().includes(this.prefix)) + } + + override async handleMessage(message: Message, bot: Bot): Promise<void> { + const session = this.#session + const user = this.user + if (!session || !user) { + return + } + + let response = await session.prompt( + `@${message.username}: ${message.message}`, + optionsGenerator(this.#model!, this.debugLogResponses), + ) + + response = response.replace(/<think>.*?<\/think>/gs, "") + let lwResponse = response.toLowerCase() + + if (lwResponse.startsWith("ai")) { + response = response.substring(2).trim() + lwResponse = response.toLowerCase() + } + + if (lwResponse.startsWith(`@${user.username.toLowerCase()}`)) { + response = response.substring(user.username.length + 1).trim() + lwResponse = response.toLowerCase() + } + + if (lwResponse.startsWith(`@${message.username.toLowerCase()}`)) { + response = response.substring(message.username.length + 1).trim() + lwResponse = response.toLowerCase() + } + + response = trimStart(response, ":").trim() + bot.send("send_message", message.channelUID, response) + } +} diff --git a/src/msg-handlers/ping-handler.ts b/src/msg-handlers/ping-handler.ts new file mode 100644 index 0000000..1ce3914 --- /dev/null +++ b/src/msg-handlers/ping-handler.ts @@ -0,0 +1,12 @@ +import { BaseHandler } from "./base-handler.ts" +import { Bot, Message } from "../snek/snek-socket.ts" + +export class PingHandler extends BaseHandler { + constructor() { + super("ping") + } + + override handleMessage(message: Message, bot: Bot): void { + message.reply("pong") + } +} diff --git a/src/snek/snek-socket.ts b/src/snek/snek-socket.ts new file mode 100644 index 0000000..7d51e27 --- /dev/null +++ b/src/snek/snek-socket.ts @@ -0,0 +1,295 @@ +import {EventEmitter} from "node:events" +import {debounce} from "npm:lodash-es" +import {getLogger} from "@logtape/logtape" + +const logger = getLogger(["ws-socket"]) + +export const BASE_URL = "https://snek.molodetz.nl/login.json" + +const baseRequest = async ( + action: string, + username: string, + password: string, +) => { + const loginPayloadRed = await fetch(BASE_URL) + console.log(loginPayloadRed) + const basePayload = await loginPayloadRed.json() + + basePayload.fields.username.value = username + basePayload.fields.password.value = password + + return await fetch(BASE_URL, { + method: "POST", + headers: { + "Content-Type": "application/json", + }, + body: JSON.stringify({ + action, + form: basePayload, + }), + }) +} + +export const login = async (username: string, password: string) => { + const loginResult = await baseRequest("submit", username, password) + + const loginPayload = await loginResult.json() + if (!("redirect_url" in loginPayload)) { + return null + } + const cookies = loginResult.headers.getSetCookie() + const authCookie = + cookies.filter((v) => v.includes("AIOHTTP_SESSION")).flatMap((v) => { + try { + return v.matchAll( + /(AIOHTTP_SESSION="?.*?"?)(?:;|^)/g, + )?.next()?.value?.[1] + } catch (e) { + return undefined + } + })[0] + + return authCookie || null +} + +export const validate = async (username: string, password: string) => { + return await baseRequest("validate", username, password) +} + +export interface User { + color: string + created_at: string + email?: string | null + last_ping: string | null + nick: string + uid: string + updated_at: string + username: string +} + +export interface Channel { + name: string + uid: string + is_moderator: boolean + is_read_only: boolean + tag: string +} + +export class Message { + message: string + html: string + userUID: string + color: string + channelUID: string + createdAt: string + updatedAt: string | null + username: string + uid: string + userNick: string + + bot: Bot + + constructor(data: any, bot: Bot) { + this.message = data.message + this.html = data.html + this.userUID = data.user_uid + this.color = data.color + this.channelUID = data.channel_uid + this.createdAt = data.created_at + this.updatedAt = data.updated_at + this.username = data.username + this.uid = data.uid + this.userNick = data.user_nick + this.bot = bot + } + + reply(message: string) { + return this.bot.send("send_message", this.channelUID, message) + } +} + +export class ConnectionClosedError extends Error { + constructor(code: number, reason: string) { + super(`Connection closed with code ${code}: ${reason}`) + } +} + +export class Bot extends EventEmitter< + { message: Message[]; close: { code: number; reason: string }[] } +> { + readonly #username: string + readonly #password: string + readonly #url: string | URL + #ws: WebSocket | null = null + + #processingMessages = new Map< + string, + { + data: PromiseWithResolvers<unknown> + when: Date + req: { + name: string + args: unknown[] + callId: string + } + } + >() + + autoReconnect = true + + get channels() { + return this.send<Channel[]>("get_channels") + } + + get user() { + return this.send<User>("get_user", null) + } + get messages() { + return this.send("get_messages", null) + } + + #authCookie: string | null = null + + get authCookie() { + return this.#authCookie + ? Promise.resolve(this.#authCookie) + : login(this.#username, this.#password).then(( + cookie, + ) => (this.#authCookie = cookie)) + } + + constructor( + username: string, + password: string, + url: string | URL = "wss://snek.molodetz.nl/rpc.ws", + ) { + super() + this.#username = username + this.#password = password + this.#url = url + } + + send<T>(name: string, ...args: unknown[]) { + const ws = this.#ws + if (ws && ws.readyState === ws.OPEN) { + const callId = Math.random().toString(36).slice(2) + logger.debug("Sending message", { name, args, callId }) + const res = Promise.withResolvers<T>() + this.#processingMessages.set(callId, { + data: res as PromiseWithResolvers<unknown>, + when: new Date(), + req: { name, args, callId }, + }) + ws.send(JSON.stringify({ + method: name, + args: args, + callId, + })) + + return res.promise.catch((e: unknown): typeof res.promise => { + logger.error("Error sending message, retrying", { + name, + args, + callId, + e, + }) + + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve(this.connect().then(() => this.send(name, ...args))) + }, 1000) + }) + }) + } + return Promise.reject(new Error("Connection not open")) + } + + receive(data: string) { + const parsedData = JSON.parse(data) + const callId = parsedData.callId + + const message = this.#processingMessages.get(callId) + if (message) { + logger.debug("Resolving message", { + data: parsedData.data, + callId, + raw: parsedData, + }) + message.data.resolve(parsedData.data) + this.#processingMessages.delete(callId) + } else { + logger.debug("Emitting message", parsedData) + this.emit("message", new Message(parsedData, this)) + } + } + + connect = debounce( + function (this: Bot) { + if (this.#ws) { + return this.send("get_user", null) + } + logger.debug("Connecting to", { url: this.#url }) + const connectedPromise = Promise.withResolvers<unknown>() + + this.#ws = new WebSocket(this.#url) + this.#ws.onopen = () => { + logger.debug("Connected") + connectedPromise.resolve( + this.send("login", this.#username, this.#password), + ) + } + this.#ws.onmessage = (event) => { + logger.debug("Received message", { data: event.data }) + this.receive(event.data) + } + + this.#ws.onclose = (event) => { + logger.warn("Connection closed", { + code: event.code, + reason: event.reason, + }) + + this.#ws = null + this.emit("close", { code: event.code, reason: event.reason }) + this.#processingMessages.forEach((message) => { + message.data.reject( + new ConnectionClosedError(event.code, event.reason), + ) + }) + this.#processingMessages.clear() + + if (this.autoReconnect) { + this.connect() + } + } + + this.#ws.onerror = (event) => { + logger.error("Connection error", { event }) + } + + return connectedPromise.promise + }, + 100, + { leading: true, trailing: false }, + ) + + sendMessage(channelUID: string, message: string) { + return this.send("send_message", channelUID, message) + } + + async uploadFiles(channelUID: string, ...files: File[]) { + const imageForm = new FormData() + imageForm.append("channel_uid", channelUID) + files.forEach((file) => { + imageForm.append("files[]", file) + }) + + return await fetch("https://snek.molodetz.nl/drive.bin", { + method: "POST", + body: imageForm, + headers: { + "Cookie": await this.authCookie, + }, + }) + } +} diff --git a/src/util/img-gen.ts b/src/util/img-gen.ts new file mode 100644 index 0000000..bf454ab --- /dev/null +++ b/src/util/img-gen.ts @@ -0,0 +1,133 @@ +import {randomUUID} from "node:crypto" +import {getLogger} from "@logtape/logtape" + +const logger = getLogger(["img-gen"]) +export class ImgGen { + #host: string + #clientId = randomUUID() + #ws: WebSocket + + #promptQueue = new Map< + string, + { promise: PromiseWithResolvers<unknown[]>; msgs: unknown[] } + >() + + constructor(host: string = "127.0.0.1:8188") { + this.#host = host + this.#initiateWebSocket() + } + + async queuePrompt(prompt: string) { + const response = await fetch(`http://${this.#host}/prompt`, { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ prompt, client_id: this.#clientId }), + }) + return await response.json() + } + + async getImage(filename: string, subfolder: string, folderType: string) { + const response = await fetch( + `http://${this.#host}/view?${ + new URLSearchParams({ filename, subfolder, type: folderType }) + .toString() + }`, + ) + return await response.arrayBuffer() + } + + async getHistory(promptId: string) { + const response = await fetch(`http://${this.#host}/history/${promptId}`) + return await response.json() + } + + #initiateWebSocket() { + if ( + !this.#ws || this.#ws.readyState === this.#ws.CLOSED || + this.#ws.readyState === this.#ws.CLOSING + ) { + const res = Promise.withResolvers<void>() + this.#ws = new WebSocket( + `ws://${this.#host}/ws?clientId=${this.#clientId}`, + ) + let lastExportId: string | null = null + this.#ws.addEventListener("message", (event) => { + if (typeof event.data === "string") { + console.log("Received message", event, event.data) + const data = JSON.parse(event.data) + const res = this.#promptQueue.get(data.data.prompt_id) + if (res) { + res.msgs.push(data) + if (data.type === "execution_success") { + res.promise.resolve(res.msgs) + this.#promptQueue.delete(data.data.prompt_id) + } else if (data.type === "executing") { + if (data.data.node === "save_image_websocket_node") { + lastExportId = data.data.prompt_id + } + } + } + } else { + console.error( + "Received img message", + event, + "assuming is part of", + lastExportId, + ) + if (lastExportId) { + const res = this.#promptQueue.get(lastExportId) + if (res) { + res.msgs.push(event.data) + } + } + } + }) + this.#ws.addEventListener("open", () => { + res.resolve() + }, { once: true }) + + this.#ws.addEventListener("close", () => { + logger.error("WebSocket closed") + + for (const [_, { promise }] of this.#promptQueue) { + promise.reject(new Error("WebSocket closed")) + } + + this.#promptQueue.clear() + + this.#ws = null + this.#initiateWebSocket() + }) + + this.#ws.addEventListener("error", (e) => { + logger.error("WebSocket error", {e}) + }) + + return res.promise + } else if (this.#ws.readyState === this.#ws.CONNECTING) { + return new Promise<void>((resolve) => { + this.#ws.addEventListener("open", () => { + resolve() + }, { once: true }) + }) + } + + return Promise.resolve() + } + + async dispatchPrompt(prompt: Record<string, unknown> | string) { + const res = Promise.withResolvers<unknown[]>() + + await this.#initiateWebSocket() + + if (this.#ws.readyState !== this.#ws.OPEN) { + return Promise.reject(new Error("WebSocket not open")) + } + + const promptData = await this.queuePrompt(prompt as string) + console.log("Prompt data", promptData) + this.#promptQueue.set(promptData.prompt_id, { promise: res, msgs: [] }) + + return res.promise + } +} diff --git a/src/util/logging.ts b/src/util/logging.ts new file mode 100644 index 0000000..5e06077 --- /dev/null +++ b/src/util/logging.ts @@ -0,0 +1,25 @@ +import {configure, getConsoleSink} from "@logtape/logtape"; + +await configure({ + sinks: { + console: getConsoleSink( + { + formatter: (logEvent) => { + const { timestamp, level, category, message, properties } = logEvent + return `${timestamp} [${level.toUpperCase()}] [${category}] ${message} ${ + properties && Object.keys(properties).length + ? JSON.stringify(properties) + : "" + }` + }, + }, + ), + }, + loggers: [ + { category: "ai-app", lowestLevel: "debug", sinks: ["console"] }, + { category: "img-gen", lowestLevel: "debug", sinks: ["console"] }, + { category: "img-gen-handler", lowestLevel: "debug", sinks: ["console"] }, + { category: "llama-gen-handler", lowestLevel: "debug", sinks: ["console"] }, + { category: "ws-socket", lowestLevel: "debug", sinks: ["console"] }, + ], +}) diff --git a/src/ws-snek-image-bot.ts b/src/ws-snek-image-bot.ts new file mode 100644 index 0000000..af2e83e --- /dev/null +++ b/src/ws-snek-image-bot.ts @@ -0,0 +1,19 @@ +import "@std/dotenv/load" +import "./util/logging.ts" +import {Bot} from "./snek/snek-socket.ts" +import {PingHandler} from "./msg-handlers/ping-handler.ts"; +import {ImgGenHandler} from "./msg-handlers/img-gen-handler.ts"; + +const bot = new Bot( + Deno.env.get("SNEK_USERNAME")!, + Deno.env.get("SNEK_PASSWORD")!, +) + +await bot.connect() + +const user = await bot.user + +console.log("We are user: ", user, await bot.authCookie) + +new PingHandler().bind(bot) +new ImgGenHandler().bind(bot) diff --git a/src/ws-snek-llama-bot.ts b/src/ws-snek-llama-bot.ts new file mode 100644 index 0000000..78b170c --- /dev/null +++ b/src/ws-snek-llama-bot.ts @@ -0,0 +1,24 @@ +import "@std/dotenv/load" +import "./util/logging.ts" +import {Bot} from "./snek/snek-socket.ts" +import {PingHandler} from "./msg-handlers/ping-handler.ts"; +import {LLamaHandler} from "./msg-handlers/llama-handler.ts"; + +const bot = new Bot( + Deno.env.get("SNEK_USERNAME")!, + Deno.env.get("SNEK_PASSWORD")!, +) + +await bot.connect() + +const user = await bot.user + +console.log("We are user: ", user, await bot.authCookie) + +await Promise.all([ + new PingHandler().bind(bot), + new LLamaHandler( + Deno.env.get("SNEK_LLAMA_MODEL")!, + Deno.env.get("SNEK_LLAMA_SYSTEM_PROMPT")!, + ).bind(bot), +]) diff --git a/templates/img-gen/SD3.5-large-turbo.eta b/templates/img-gen/SD3.5-large-turbo.eta new file mode 100644 index 0000000..123822f --- /dev/null +++ b/templates/img-gen/SD3.5-large-turbo.eta @@ -0,0 +1,199 @@ +{ + "4": { + "inputs": { + "ckpt_name": "stableDiffusion35_largeTurbo.safetensors" + }, + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } + }, + "6": { + "inputs": { + "text": "<%= it.prompt %>", + "clip": [ + "11", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "8": { + "inputs": { + "samples": [ + "294", + 0 + ], + "vae": [ + "4", + 2 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "11": { + "inputs": { + "clip_name1": "clip_g.safetensors", + "clip_name2": "clip_l.safetensors", + "clip_name3": "t5xxl_fp16.safetensors" + }, + "class_type": "TripleCLIPLoader", + "_meta": { + "title": "TripleCLIPLoader" + } + }, + "13": { + "inputs": { + "shift": 3, + "model": [ + "4", + 0 + ] + }, + "class_type": "ModelSamplingSD3", + "_meta": { + "title": "ModelSamplingSD3" + } + }, + "67": { + "inputs": { + "conditioning": [ + "71", + 0 + ] + }, + "class_type": "ConditioningZeroOut", + "_meta": { + "title": "ConditioningZeroOut" + } + }, + "68": { + "inputs": { + "start": 0.1, + "end": 1, + "conditioning": [ + "67", + 0 + ] + }, + "class_type": "ConditioningSetTimestepRange", + "_meta": { + "title": "ConditioningSetTimestepRange" + } + }, + "69": { + "inputs": { + "conditioning_1": [ + "68", + 0 + ], + "conditioning_2": [ + "70", + 0 + ] + }, + "class_type": "ConditioningCombine", + "_meta": { + "title": "Conditioning (Combine)" + } + }, + "70": { + "inputs": { + "start": 0, + "end": 0.1, + "conditioning": [ + "71", + 0 + ] + }, + "class_type": "ConditioningSetTimestepRange", + "_meta": { + "title": "ConditioningSetTimestepRange" + } + }, + "71": { + "inputs": { + "text": "<%= it.negativePrompt ||'' %>", + "clip": [ + "11", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "135": { + "inputs": { + "width": <%= it.width || 1024 %>, + "height": <%= it.height || 1024 %>, + "batch_size": <%= it.batchSize || 1 %> + }, + "class_type": "EmptySD3LatentImage", + "_meta": { + "title": "EmptySD3LatentImage" + } + }, + "294": { + "inputs": { + "seed": <%= it.seed || it.randomSeed() %>, + "steps": <%= it.steps || 2 %>, + "cfg": <%= it.cfg || 1 %>, + "sampler_name": "<%= it.sampler || "euler" %>", + "scheduler": "beta", + "denoise": 1, + "model": [ + "13", + 0 + ], + "positive": [ + "6", + 0 + ], + "negative": [ + "69", + 0 + ], + "latent_image": [ + "135", + 0 + ] + }, + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } + }, + "301": { + "inputs": { + "filename_prefix": "ComfyUI", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } + }, + "save_image_websocket_node": { + "inputs": { + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImageWebsocket", + "_meta": { + "title": "SaveImageWebsocket" + } + } +} \ No newline at end of file diff --git a/templates/img-gen/SD3.5-large.eta b/templates/img-gen/SD3.5-large.eta new file mode 100644 index 0000000..27c21c5 --- /dev/null +++ b/templates/img-gen/SD3.5-large.eta @@ -0,0 +1,199 @@ +{ + "4": { + "inputs": { + "ckpt_name": "stableDiffusion35_large.safetensors" + }, + "class_type": "CheckpointLoaderSimple", + "_meta": { + "title": "Load Checkpoint" + } + }, + "6": { + "inputs": { + "text": "<%= it.prompt %>", + "clip": [ + "11", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "8": { + "inputs": { + "samples": [ + "294", + 0 + ], + "vae": [ + "4", + 2 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "11": { + "inputs": { + "clip_name1": "clip_g.safetensors", + "clip_name2": "clip_l.safetensors", + "clip_name3": "t5xxl_fp16.safetensors" + }, + "class_type": "TripleCLIPLoader", + "_meta": { + "title": "TripleCLIPLoader" + } + }, + "13": { + "inputs": { + "shift": 3, + "model": [ + "4", + 0 + ] + }, + "class_type": "ModelSamplingSD3", + "_meta": { + "title": "ModelSamplingSD3" + } + }, + "67": { + "inputs": { + "conditioning": [ + "71", + 0 + ] + }, + "class_type": "ConditioningZeroOut", + "_meta": { + "title": "ConditioningZeroOut" + } + }, + "68": { + "inputs": { + "start": 0.1, + "end": 1, + "conditioning": [ + "67", + 0 + ] + }, + "class_type": "ConditioningSetTimestepRange", + "_meta": { + "title": "ConditioningSetTimestepRange" + } + }, + "69": { + "inputs": { + "conditioning_1": [ + "68", + 0 + ], + "conditioning_2": [ + "70", + 0 + ] + }, + "class_type": "ConditioningCombine", + "_meta": { + "title": "Conditioning (Combine)" + } + }, + "70": { + "inputs": { + "start": 0, + "end": 0.1, + "conditioning": [ + "71", + 0 + ] + }, + "class_type": "ConditioningSetTimestepRange", + "_meta": { + "title": "ConditioningSetTimestepRange" + } + }, + "71": { + "inputs": { + "text": "<%= it.negativePrompt ||'' %>", + "clip": [ + "11", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "135": { + "inputs": { + "width": <%= it.width || 1024 %>, + "height": <%= it.height || 1024 %>, + "batch_size": <%= it.batchSize || 1 %> + }, + "class_type": "EmptySD3LatentImage", + "_meta": { + "title": "EmptySD3LatentImage" + } + }, + "294": { + "inputs": { + "seed": <%= it.seed || it.randomSeed() %>, + "steps": <%= it.steps || 2 %>, + "cfg": <%= it.cfg || 1 %>, + "sampler_name": "<%= it.sampler || "euler" %>", + "scheduler": "beta", + "denoise": 1, + "model": [ + "13", + 0 + ], + "positive": [ + "6", + 0 + ], + "negative": [ + "69", + 0 + ], + "latent_image": [ + "135", + 0 + ] + }, + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } + }, + "301": { + "inputs": { + "filename_prefix": "ComfyUI", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } + }, + "save_image_websocket_node": { + "inputs": { + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImageWebsocket", + "_meta": { + "title": "SaveImageWebsocket" + } + } +} \ No newline at end of file diff --git a/templates/img-gen/flux-dev.eta b/templates/img-gen/flux-dev.eta new file mode 100644 index 0000000..5cb7547 --- /dev/null +++ b/templates/img-gen/flux-dev.eta @@ -0,0 +1,204 @@ +{ + "5": { + "inputs": { + "width": <%= it.width || 1024 %>, + "height": <%= it.height || 1024 %>, + "batch_size": <%= it.batchSize || 1 %> + }, + "class_type": "EmptyLatentImage", + "_meta": { + "title": "Empty Latent Image" + } + }, + "6": { + "inputs": { + "text": "<%= it.prompt ||'' %>", + "clip": [ + "11", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "8": { + "inputs": { + "samples": [ + "13", + 0 + ], + "vae": [ + "10", + 0 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "9": { + "inputs": { + "filename_prefix": "MarkuryFLUX", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImage", + "_meta": { + "title": "Save Image" + } + }, + "10": { + "inputs": { + "vae_name": "ae.safetensors" + }, + "class_type": "VAELoader", + "_meta": { + "title": "Load VAE" + } + }, + "11": { + "inputs": { + "clip_name1": "t5xxl_fp16.safetensors", + "clip_name2": "clip_l.safetensors", + "type": "flux", + "device": "default" + }, + "class_type": "DualCLIPLoader", + "_meta": { + "title": "DualCLIPLoader" + } + }, + "12": { + "inputs": { + "unet_name": "flux_dev.safetensors", + "weight_dtype": "fp8_e4m3fn" + }, + "class_type": "UNETLoader", + "_meta": { + "title": "Load Diffusion Model" + } + }, + "13": { + "inputs": { + "noise": [ + "25", + 0 + ], + "guider": [ + "22", + 0 + ], + "sampler": [ + "16", + 0 + ], + "sigmas": [ + "17", + 0 + ], + "latent_image": [ + "5", + 0 + ] + }, + "class_type": "SamplerCustomAdvanced", + "_meta": { + "title": "SamplerCustomAdvanced" + } + }, + "16": { + "inputs": { + "sampler_name": "<%= it.sampler || "euler" %>" + }, + "class_type": "KSamplerSelect", + "_meta": { + "title": "KSamplerSelect" + } + }, + "17": { + "inputs": { + "scheduler": "beta", + "steps": <%= it.steps || 30 %>, + "denoise": 1, + "model": [ + "61", + 0 + ] + }, + "class_type": "BasicScheduler", + "_meta": { + "title": "BasicScheduler" + } + }, + "22": { + "inputs": { + "model": [ + "61", + 0 + ], + "conditioning": [ + "60", + 0 + ] + }, + "class_type": "BasicGuider", + "_meta": { + "title": "BasicGuider" + } + }, + "25": { + "inputs": { + "noise_seed": <%= it.seed || it.randomSeed() %> + }, + "class_type": "RandomNoise", + "_meta": { + "title": "RandomNoise" + } + }, + "60": { + "inputs": { + "guidance": 4, + "conditioning": [ + "6", + 0 + ] + }, + "class_type": "FluxGuidance", + "_meta": { + "title": "FluxGuidance" + } + }, + "61": { + "inputs": { + "max_shift": 1.15, + "base_shift": 0.5, + "width": <%= it.width || 1024 %>, + "height": <%= it.height || 1024 %>, + "model": [ + "12", + 0 + ] + }, + "class_type": "ModelSamplingFlux", + "_meta": { + "title": "ModelSamplingFlux" + } + }, + "save_image_websocket_node": { + "inputs": { + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveImageWebsocket", + "_meta": { + "title": "SaveImageWebsocket" + } + } +} \ No newline at end of file diff --git a/templates/img-gen/mochi.eta b/templates/img-gen/mochi.eta new file mode 100644 index 0000000..e9ccb31 --- /dev/null +++ b/templates/img-gen/mochi.eta @@ -0,0 +1,149 @@ +{ + "3": { + "inputs": { + "seed": <%= it.seed || it.randomSeed() %>, + "steps": <%= it.steps || 30 %>, + "cfg": <%= it.cfg || 4.5 %>, + "sampler_name": "<%= it.sampler || "euler" %>", + "scheduler": "beta", + "denoise": 1, + "model": [ + "37", + 0 + ], + "positive": [ + "6", + 0 + ], + "negative": [ + "7", + 0 + ], + "latent_image": [ + "21", + 0 + ] + }, + "class_type": "KSampler", + "_meta": { + "title": "KSampler" + } + }, + "6": { + "inputs": { + "text": "<%= it.prompt %>", + "clip": [ + "38", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "7": { + "inputs": { + "text": "<%= it.negativePrompt || '' %>", + "clip": [ + "38", + 0 + ] + }, + "class_type": "CLIPTextEncode", + "_meta": { + "title": "CLIP Text Encode (Prompt)" + } + }, + "8": { + "inputs": { + "samples": [ + "3", + 0 + ], + "vae": [ + "39", + 0 + ] + }, + "class_type": "VAEDecode", + "_meta": { + "title": "VAE Decode" + } + }, + "21": { + "inputs": { + "width": <%= it.width || 848 %>, + "height": <%= it.height || 480 %>, + "length": <%= it.frames || 37 %>, + "batch_size": <%= it.batchSize || 1 %> + }, + "class_type": "EmptyMochiLatentVideo", + "_meta": { + "title": "EmptyMochiLatentVideo" + } + }, + "28": { + "inputs": { + "filename_prefix": "ComfyUI", + "fps": 24, + "lossless": false, + "quality": 80, + "method": "default", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveAnimatedWEBP", + "_meta": { + "title": "SaveAnimatedWEBP" + } + }, + "37": { + "inputs": { + "unet_name": "mochi_preview_bf16.safetensors", + "weight_dtype": "default" + }, + "class_type": "UNETLoader", + "_meta": { + "title": "Load Diffusion Model" + } + }, + "38": { + "inputs": { + "clip_name": "t5xxl_fp16.safetensors", + "type": "mochi", + "device": "default" + }, + "class_type": "CLIPLoader", + "_meta": { + "title": "Load CLIP" + } + }, + "39": { + "inputs": { + "vae_name": "mochi_vae.safetensors" + }, + "class_type": "VAELoader", + "_meta": { + "title": "Load VAE" + } + }, + "save_image_websocket_node": { + "inputs": { + "fps": 24, + "lossless": false, + "quality": 80, + "method": "default", + "images": [ + "8", + 0 + ] + }, + "class_type": "SaveAnimatedWEBPWebsocket", + "_meta": { + "title": "SaveAnimatedWEBPWebsocket" + } + } +} \ No newline at end of file