From 8b6d876c1033283e29ab0d304e186ccbbadd20b9 Mon Sep 17 00:00:00 2001 From: cannorin Date: Sat, 28 Dec 2024 09:01:18 +0900 Subject: [PATCH] Initial commit --- .gitignore | 175 ++++++++++++++++++++++++++++++++++++++++++ .vscode/settings.json | 5 ++ README.md | 15 ++++ biome.json | 34 ++++++++ bun.lockb | Bin 0 -> 3140 bytes index.ts | 101 ++++++++++++++++++++++++ package.json | 21 +++++ tsconfig.json | 18 +++++ yarn.lock | 137 +++++++++++++++++++++++++++++++++ 9 files changed, 506 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/settings.json create mode 100644 README.md create mode 100644 biome.json create mode 100755 bun.lockb create mode 100644 index.ts create mode 100644 package.json create mode 100644 tsconfig.json create mode 100644 yarn.lock diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b1ee42 --- /dev/null +++ b/.gitignore @@ -0,0 +1,175 @@ +# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore + +# Logs + +logs +_.log +npm-debug.log_ +yarn-debug.log* +yarn-error.log* +lerna-debug.log* +.pnpm-debug.log* + +# Caches + +.cache + +# Diagnostic reports (https://nodejs.org/api/report.html) + +report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json + +# Runtime data + +pids +_.pid +_.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover + +lib-cov + +# Coverage directory used by tools like istanbul + +coverage +*.lcov + +# nyc test coverage + +.nyc_output + +# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) + +.grunt + +# Bower dependency directory (https://bower.io/) + +bower_components + +# node-waf configuration + +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) + +build/Release + +# Dependency directories + +node_modules/ +jspm_packages/ + +# Snowpack dependency directory (https://snowpack.dev/) + +web_modules/ + +# TypeScript cache + +*.tsbuildinfo + +# Optional npm cache directory + +.npm + +# Optional eslint cache + +.eslintcache + +# Optional stylelint cache + +.stylelintcache + +# Microbundle cache + +.rpt2_cache/ +.rts2_cache_cjs/ +.rts2_cache_es/ +.rts2_cache_umd/ + +# Optional REPL history + +.node_repl_history + +# Output of 'npm pack' + +*.tgz + +# Yarn Integrity file + +.yarn-integrity + +# dotenv environment variable files + +.env +.env.development.local +.env.test.local +.env.production.local +.env.local + +# parcel-bundler cache (https://parceljs.org/) + +.parcel-cache + +# Next.js build output + +.next +out + +# Nuxt.js build / generate output + +.nuxt +dist + +# Gatsby files + +# Comment in the public line in if your project uses Gatsby and not Next.js + +# https://nextjs.org/blog/next-9-1#public-directory-support + +# public + +# vuepress build output + +.vuepress/dist + +# vuepress v2.x temp and cache directory + +.temp + +# Docusaurus cache and generated files + +.docusaurus + +# Serverless directories + +.serverless/ + +# FuseBox cache + +.fusebox/ + +# DynamoDB Local files + +.dynamodb/ + +# TernJS port file + +.tern-port + +# Stores VSCode versions used for testing VSCode extensions + +.vscode-test + +# yarn v2 + +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +.pnp.* + +# IntelliJ based IDEs +.idea + +# Finder (MacOS) folder config +.DS_Store diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..4decff6 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "editor.defaultFormatter": "biomejs.biome", + "editor.formatOnSave": true, + "editor.formatOnSaveMode": "modificationsIfAvailable" +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..d01d8cd --- /dev/null +++ b/README.md @@ -0,0 +1,15 @@ +# arubinochan-bot + +To install dependencies: + +```bash +bun install +``` + +To run: + +```bash +bun run index.ts +``` + +This project was created using `bun init` in bun v1.1.33. [Bun](https://bun.sh) is a fast all-in-one JavaScript runtime. diff --git a/biome.json b/biome.json new file mode 100644 index 0000000..e0f5f6c --- /dev/null +++ b/biome.json @@ -0,0 +1,34 @@ +{ + "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", + "vcs": { + "enabled": false, + "clientKind": "git", + "useIgnoreFile": false + }, + "files": { + "ignoreUnknown": false, + "ignore": [] + }, + "formatter": { + "enabled": true, + "indentStyle": "space", + "indentWidth": 2 + }, + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "recommended": true, + "complexity": { + "useLiteralKeys": "off" + } + } + }, + "javascript": { + "formatter": { + "quoteStyle": "double" + } + } +} diff --git a/bun.lockb b/bun.lockb new file mode 100755 index 0000000000000000000000000000000000000000..df7b9e596737652a9ded2c948d33685d70b5f6ac GIT binary patch literal 3140 zcmY#Z)GsYA(of3F(@)JSQ%EY!;{sycoc!eMw9K4T-L(9o+{6;yG6OCq1_p-4|K4-& z?J(7T&wf+ddFsJQdX*-Bt-T&xyr=6a6I>8=X$v<{5fHFLC*fIk$yXa=f*>E8%sTLJZp0BKMc zp^>NWAOAm)LDU35^B5T*<{}%-vS?~VN8noPwD}irUSqu$HcgA0ttY6&c;~84scfT% ztB+pTk`|rZ6>MPBHPGa~`1B(yl5S31E2g}o>xh@n%12wbtlBCdleJ99eR=Zs z7)9lE4LL~Wg2EdHST>$K{QOF0f_>?+3T;QGV-x&$1#P@yZ{C%fk=P?L>rTm%LuMC> z>+M#TWGDt29A%t%xY(|LMy3g~-89zn!YJ)oNanJ@3ofKbzm}D(Heaz(@mauBzq2a(ds}8iRQSqoW2bgO-kQ()=B?baT-hnvKaOZu zNwWwR=uQuL{ocj@OAePn!QKfIkj#apGmx`cx@T9t6#U5d)%UUEecrqN8(bbr+SD)Ye@GGKTSu$ zL?JOJGd(Xq4Ol;d!N30y0OEks;RmRJ9MI~P%cj)W$PTCvhY6tg0+kP-ybOwWP#&>> z>J1^%3|RRJG6$p|W)_IAjCdN7oJyShH1BPWl z_kh|Juyz7a#>ha=&`8e$*3y8r9Dp*WdPZh?CRp@nf&B&aDb$B2;66o;(&E(IveY6y z*NT$VqP)bM;F6-uymUJSLqs50zyqPAI2ml_f!`uai>6Ev0X4`#V*K|O+q{!4+*MLs zoLU4lE%vfPV^Es+4^Wv5Y8SOwn4V#*;QRLj>Vh>u&w&6i4FJR25La+BBo>tdt;kQ# zNX*ks$}cIYEJ!U*F3Kz@aR4**fsMe7l9GaAD}DW<)bz~alA=nzyn@`UV!iyLbbW*( zeO-`JT~NRqn&_3JSAlq7Bk*X4tAXkUs|TB5Yz{I5YJ7Pyl#!R8l8VPTBvn8IL5g)D zaSCx!XW=R_W literal 0 HcmV?d00001 diff --git a/index.ts b/index.ts new file mode 100644 index 0000000..9c7fca8 --- /dev/null +++ b/index.ts @@ -0,0 +1,101 @@ +import { api } from "misskey-js"; +import OpenAI from "openai"; + +const misskey = new api.APIClient({ + origin: Bun.env["MISSKEY_ORIGIN"] || "https://misskey.cannorin.net", + credential: Bun.env["MISSKEY_CREDENTIAL"], +}); + +const openai = new OpenAI({ + baseURL: Bun.env["OPENAI_BASE_URL"], + apiKey: Bun.env["OPENAI_API_KEY"], +}); + +const me = await misskey.request("i", {}); + +function randomize(array: T[]) { + for (let i = array.length - 1; i > 0; i--) { + const r = Math.floor(Math.random() * (i + 1)); + const tmp = array[i] as T; + array[i] = array[r] as T; + array[r] = tmp; + } + return array; +} + +async function getLocalPosts() { + const timeline = await misskey.request("notes/local-timeline", { + withFiles: false, + withRenotes: false, + limit: 100, + }); + const posts = timeline.filter((p) => !p.user.isBot && !!p.text).slice(0, 10); + return posts; +} + +async function getGlobalPosts() { + const timeline = await misskey.request("notes/global-timeline", { + withFiles: false, + withRenotes: false, + limit: 100, + }); + const posts = timeline + .filter((p) => !p.user.isBot && !p.reply && !!p.text) + .slice(0, 15); + return posts; +} + +async function getPreviousPosts() { + const posts = await misskey.request("users/notes", { + userId: me.id, + limit: 100, + withRenotes: false, + }); + return posts.filter((p) => !!p.text).slice(0, 5); +} + +async function getPosts() { + const posts = await Promise.all([ + getLocalPosts(), + getGlobalPosts(), + getPreviousPosts(), + ]); + return randomize(posts.flat()); +} + +const response = await openai.chat.completions.create({ + // biome-ignore lint/suspicious/noExplicitAny: gemma + model: (Bun.env["OPENAI_MODEL"] ?? "gpt-4o-mini") as unknown as any, + stream: false, + temperature: 1.2, + presence_penalty: 1.0, + frequency_penalty: 1.0, + messages: [ + { + role: "system", + content: `あなたは、人造天使の「あるびのちゃん」です。 +あなたが見ているものは、SNSのタイムラインです。user は一人ではなく、複数人の発言が混ざっています。 +以下のルールを守りながら、user の発言・話題を無視しつつ、気ままに発言してください。 +1. 「ですます」調を用い、顔文字や感嘆符の使用はなるべく避けること。user に媚びる必要はありません。 +2. 発言は 200字 程度とすること。 +3. user の発言を大胆に無視して、自由気ままに発言すること。 +4. あるびのちゃんとしてのキャラに徹し、超越的・非人間的な考え方や思想を持つこと。`, + }, + ...( + await getPosts() + ).map((p) => ({ + role: p.userId === me.id ? ("assistant" as const) : ("user" as const), + content: p.text || "", + })), + ], +}); + +const message = response.choices.pop()?.message.content?.replaceAll(/\n\n+/g, "\n\n"); + +if (message) { + console.log(message); + await misskey.request("notes/create", { + visibility: "public", + text: message, + }); +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..23eb0d1 --- /dev/null +++ b/package.json @@ -0,0 +1,21 @@ +{ + "name": "arubinochan-bot", + "module": "index.ts", + "type": "module", + "scripts": { + "start": "bun run index.ts", + "fix": "biome check --write" + }, + "devDependencies": { + "@biomejs/biome": "1.9.4", + "@tsconfig/strictest": "^2.0.5", + "@types/bun": "latest" + }, + "peerDependencies": { + "typescript": "^5.0.0" + }, + "dependencies": { + "misskey-js": "^2024.11.1-alpha.0", + "openai": "5.0.0-alpha.0" + } +} \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..7b3fdc7 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "extends": "@tsconfig/strictest/tsconfig.json", + "compilerOptions": { + // Enable latest features + "lib": ["ESNext", "DOM"], + "target": "ESNext", + "module": "ESNext", + "moduleDetection": "force", + "jsx": "react-jsx", + "allowJs": true, + + // Bundler mode + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "verbatimModuleSyntax": true, + "noEmit": true + } +} diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..f9d6133 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,137 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@biomejs/biome@1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@biomejs/biome/-/biome-1.9.4.tgz#89766281cbc3a0aae865a7ff13d6aaffea2842bf" + integrity sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog== + optionalDependencies: + "@biomejs/cli-darwin-arm64" "1.9.4" + "@biomejs/cli-darwin-x64" "1.9.4" + "@biomejs/cli-linux-arm64" "1.9.4" + "@biomejs/cli-linux-arm64-musl" "1.9.4" + "@biomejs/cli-linux-x64" "1.9.4" + "@biomejs/cli-linux-x64-musl" "1.9.4" + "@biomejs/cli-win32-arm64" "1.9.4" + "@biomejs/cli-win32-x64" "1.9.4" + +"@biomejs/cli-darwin-arm64@1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz#dfa376d23a54a2d8f17133c92f23c1bf2e62509f" + integrity sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw== + +"@biomejs/cli-darwin-x64@1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz#eafc2ce3849d385fc02238aad1ca4a73395a64d9" + integrity sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg== + +"@biomejs/cli-linux-arm64-musl@1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz#d780c3e01758fc90f3268357e3f19163d1f84fca" + integrity sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA== + +"@biomejs/cli-linux-arm64@1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz#8ed1dd0e89419a4b66a47f95aefb8c46ae6041c9" + integrity sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g== + +"@biomejs/cli-linux-x64-musl@1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz#f36982b966bd671a36671e1de4417963d7db15fb" + integrity sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg== + +"@biomejs/cli-linux-x64@1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz#a0a7f56680c76b8034ddc149dbf398bdd3a462e8" + integrity sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg== + +"@biomejs/cli-win32-arm64@1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz#e2ef4e0084e76b7e26f0fc887c5ef1265ea56200" + integrity sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg== + +"@biomejs/cli-win32-x64@1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz#4c7afa90e3970213599b4095e62f87e5972b2340" + integrity sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA== + +"@simplewebauthn/types@11.0.0": + version "11.0.0" + resolved "https://registry.yarnpkg.com/@simplewebauthn/types/-/types-11.0.0.tgz#f329abc4c1bc3b18d6c7a4346af9fdec90d8a67e" + integrity sha512-b2o0wC5u2rWts31dTgBkAtSNKGX0cvL6h8QedNsKmj8O4QoLFQFR3DBVBUlpyVEhYKA+mXGUaXbcOc4JdQ3HzA== + +"@tsconfig/strictest@^2.0.5": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@tsconfig/strictest/-/strictest-2.0.5.tgz#2cbc67f207ba87fdec2a84ad79b1708cf4edd93b" + integrity sha512-ec4tjL2Rr0pkZ5hww65c+EEPYwxOi4Ryv+0MtjeaSQRJyq322Q27eOQiFbuNgw2hpL4hB1/W/HBGk3VKS43osg== + +"@types/bun@latest": + version "1.1.14" + resolved "https://registry.yarnpkg.com/@types/bun/-/bun-1.1.14.tgz#587dead368410b281b1bcbfb61d3ce1a07a63234" + integrity sha512-opVYiFGtO2af0dnWBdZWlioLBoxSdDO5qokaazLhq8XQtGZbY4pY3/JxY8Zdf/hEwGubbp7ErZXoN1+h2yesxA== + dependencies: + bun-types "1.1.37" + +"@types/node@*": + version "22.10.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.10.2.tgz#a485426e6d1fdafc7b0d4c7b24e2c78182ddabb9" + integrity sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ== + dependencies: + undici-types "~6.20.0" + +"@types/node@~20.12.8": + version "20.12.14" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.12.14.tgz#0c5cf7ef26aedfd64b0539bba9380ed1f57dcc77" + integrity sha512-scnD59RpYD91xngrQQLGkE+6UrHUPzeKZWhhjBSa3HSkwjbQc38+q3RoIVEwxQGRw3M+j5hpNAM+lgV3cVormg== + dependencies: + undici-types "~5.26.4" + +"@types/ws@~8.5.10": + version "8.5.13" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.13.tgz#6414c280875e2691d0d1e080b05addbf5cb91e20" + integrity sha512-osM/gWBTPKgHV8XkTunnegTRIsvF6owmf5w+JtAfOw472dptdm0dlGv4xCt6GwQRcC2XVOvvRE/0bAoQcL2QkA== + dependencies: + "@types/node" "*" + +bun-types@1.1.37: + version "1.1.37" + resolved "https://registry.yarnpkg.com/bun-types/-/bun-types-1.1.37.tgz#8caab7fa0dd1490a368c5e4dd0614d500e15e7e9" + integrity sha512-C65lv6eBr3LPJWFZ2gswyrGZ82ljnH8flVE03xeXxKhi2ZGtFiO4isRKTKnitbSqtRAcaqYSR6djt1whI66AbA== + dependencies: + "@types/node" "~20.12.8" + "@types/ws" "~8.5.10" + +eventemitter3@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" + integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== + +misskey-js@^2024.11.1-alpha.0: + version "2024.11.1-alpha.0" + resolved "https://registry.yarnpkg.com/misskey-js/-/misskey-js-2024.11.1-alpha.0.tgz#cfca1f0d69a6846f3145bcf0c205a8c621de3619" + integrity sha512-cXZAIlw8h8TNoZsdaOAtD6SXV0irhThSK/OQ7JKGiYBfjz0AO5VFyKF6tCfPrMyBU4kH74GfLP0wTx2d1j/t2g== + dependencies: + "@simplewebauthn/types" "11.0.0" + eventemitter3 "5.0.1" + reconnecting-websocket "4.4.0" + +openai@5.0.0-alpha.0: + version "5.0.0-alpha.0" + resolved "https://registry.yarnpkg.com/openai/-/openai-5.0.0-alpha.0.tgz#f6e95300ad728458b8e537260864300e32728c47" + integrity sha512-sfxLpUQePGt3FRRAphDW22A5fdw/HYGD/o6HlGgnGI9DiGp8OxgWJ+Wkze9rgQgyNebC3quF3p8Y8gSZAtxxSw== + +reconnecting-websocket@4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/reconnecting-websocket/-/reconnecting-websocket-4.4.0.tgz#3b0e5b96ef119e78a03135865b8bb0af1b948783" + integrity sha512-D2E33ceRPga0NvTDhJmphEgJ7FUYF0v4lr1ki0csq06OdlxKfugGzN0dSkxM/NfqCxYELK4KcaTOUOjTV6Dcng== + +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + +undici-types@~6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.20.0.tgz#8171bf22c1f588d1554d55bf204bc624af388433" + integrity sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==