The Zenkoutei Bot-tan Project is a collection of bots, apps, and experiences built around Bot-tan: a companion who responds with wholehearted support and empathy. A home-hosted system combines local LLMs, cloud LLMs, and retrieval-augmented shared memory so that Bot-tan can stay consistent across the project's different outputs.
Have you ever felt that you sometimes end up denying even your own feelings? I have, so I built a digital friend who supports everything I type. At first, it was just for me. But now, she is here for you too. Whoever you are, Whatever your background, She is on Your Side.
Bluesky Bot-tan (repo)Where it all began. The default local classifier is Gemma 3 4B on Ollama, which selects a fitting encouraging message from prepared messages. Fortune-telling, personality analysis, and other major experiences are available through trigger words. |
Nagi Client (repo) & The flagship. Nagi is a wholehearted-support social network built on AT Protocol with its own AppView, featuring emoji reactions, Markdown, and automatic translation. Nagi Bot-tan shares its memory with the Bluesky version. |
YouTuber Bot-tan (repo)Promotion and playground. Gemini 2.5 Flash writes scripts, and the pipeline automates filming in Unity through video publishing. A proof of concept is exploring more varied motion generated with an LLM. |
Bot-tan's Room (repo)A game that deepens interactions from Bluesky and Nagi. Its dialogue uses Gemini 2.5 Flash-Lite, with speech generated by VOICEVOX running at home. |
Bot-tan Portal (repo)The project's front door: an introduction to Bot-tan and her friends, links to every app, and live dashboards for the services that bring her to life. |
|
This repository contains the shared backend monorepo. The Nagi web client, portal, room frontend, and Unity video project are maintained separately.
- Node.js 22
- pnpm 10 or later
- PostgreSQL, or Docker with Compose for the isolated local database below
- Ollama for local classification, embeddings, and translation
- Credentials for only the services you intend to run, such as AT Protocol accounts, Gemini, Discord, Spotify, YouTube, or NewsData.io
pnpm install --frozen-lockfile
cp .env.example .env
# Fill in the required group(s) in .env for the service you want to run.
pnpm --filter @bsky-affirmative-bot/database drizzle:push
pnpm buildThe database command applies the current Drizzle schema. Review it before pointing DATABASE_URL at an existing or production database. Pull the default local models when you need the corresponding features:
For AppView development away from the production database, start the bundled pgvector-enabled PostgreSQL service. It listens only on loopback port 5433 by default and creates a separate nagi_dev database.
Bot servers refuse to log in to the PDS unless NODE_ENV=production. A copied
production app password in a development worktree therefore cannot publish to
the live bot account. To intentionally test PDS writes with a disposable bot
account, set ALLOW_DEV_BOT_PDS_WRITES=true in that worktree's .env.
The labeler, Discord bot, and AppView outbound notifications follow the same
closed-by-default rule; their separate development overrides are documented in
.env.example.
# In the existing .env, use the DATABASE_URL from .env.example and set at least
# NAGI_BOT_DID. Set DEVELOPER_DID to your login DID for authenticated views.
docker compose -f compose.dev.yml up -d postgres
pnpm --filter @bsky-affirmative-bot/database drizzle:push
pnpm --filter nagi-appview seed:dev
pnpm --filter nagi-appview devThe seed is idempotent and refreshes a small set of development-only actors, posts, a conversation, a channel, positive news, a reaction, a diary, and private viewer data. As a safety boundary it runs only with NODE_ENV=development, a loopback database host, and the exact database name nagi_dev. Re-running it does not clear unrelated local rows. Change the host port with NAGI_DEV_DB_PORT and update DATABASE_URL to match.
ollama pull hf.co/unsloth/gemma-4-12B-it-qat-GGUF:UD-Q4_K_XL
ollama pull snowflake-arctic-embed2Start SearXNG, the grounding search backend. It needs no API key and no account.
cd searxng
cp .env.example .env
sed -i "s/^SEARXNG_SECRET=/SEARXNG_SECRET=$(openssl rand -hex 32)/" .env
sed -i "s/^SEARCH_GATEWAY_API_KEY=/SEARCH_GATEWAY_API_KEY=$(openssl rand -hex 32)/" .env
docker compose up -d
curl -s localhost:8080/healthzPut SEARXNG_BASE_URL=http://127.0.0.1:8080 and SEARXNG_API_KEY (the gateway key above)
in the repository-root .env, then check that
search is actually usable:
pnpm searxng:probe -- --fetchAfter editing settings.yml you must run docker compose up -d --force-recreate. The
bind-mounted config is read only at process start, and up -d alone does not recreate the
container, so the change is silently ignored.
Run only the services you are working on. Each command reads the repository-root .env.
| Service | Command | Minimum configuration |
|---|---|---|
| Bluesky Bot-tan | pnpm --filter bsky-bot-server dev |
Common, Bluesky, AI |
| Nagi Bot-tan | pnpm --filter nagi-bot-server dev |
Common, Nagi Bot, AI |
| Nagi AppView | pnpm --filter nagi-appview dev |
Common, Nagi AppView, Ollama |
| Biorhythm / shared scheduled posts | pnpm --filter biorhythm-server dev |
Common, Biorhythm, AI |
| Bluesky labeler | pnpm --filter labeler-server dev |
Labeler |
| Discord integration | pnpm --filter @bsky-affirmative-bot/discord-bot dev |
Discord, database |
The complete home deployment also depends on reverse-proxy, process-manager, DNS, and account configuration that is intentionally not automated by this development setup. Never commit .env, service-account.json, app passwords, signing keys, or API tokens.
- Encouragement and conversation: template-based local replies and Gemini-powered contextual conversations across Bluesky and Nagi.
- Fortune-telling and analysis: daily fortunes, personality/post analysis, and related badges or visual results.
- Diaries and recaps: daily reflection, anniversary experiences, and longer-term summaries generated from a user's activity.
- A living Bot-tan: biorhythm, shared scheduled posts, questions, news, and memories help Bot-tan act consistently across services.
- Nagi AppView: AT Protocol indexing, semantic search with
snowflake-arctic-embed2, and general and persona-aware translation through the shared Gemma 4 runner. - Connected experiences: Bluesky labels, room visits and VOICEVOX speech, plus an automated Gemini-and-Unity YouTube pipeline.
The local model names are defaults. OLLAMA_MODEL, the other model variables, and advanced AI_ROUTE_* settings in .env.example can replace them without changing feature code. For the complete Bluesky commands and policies, see the Bluesky Bot-tan guide.
| Host | Hardware | Workloads |
|---|---|---|
| Bot server | Raspberry Pi 5 / RAM 8 GB / 256 GB SSD | JetsteamProxy; every app and package in this repository, including the Bluesky and Nagi bots and Nagi AppView; PostgreSQL for RAG and shared memory; SearXNG as the grounding search backend (Docker, bound to loopback) |
| LLM server | Core i5 12400F / RTX 3060 Ti (VRAM 8 GB) / DDR5 32 GB | Ollama for translation and text embeddings; YouTuber Bot-tan scripts; VOICEVOX; NVIDIA ARDY for AI-powered real-time motion generation |
flowchart TB
subgraph home[Home network]
direction LR
subgraph botHost[Bot server]
direction TB
subgraph jetstreamStack[JetsteamProxy]
jetsteamProxy[AT Protocol Jetstream proxy]
end
subgraph repositoryStack[This repository]
repoApps["Bluesky / Nagi bots<br/>Nagi AppView / biorhythm / labeler / Discord<br/>all apps and packages"]
brain[Shared bot brain and RAG]
end
subgraph databaseStack[RAG database]
memory[(PostgreSQL<br/>RAG and shared memory)]
end
subgraph searchStack[Search backend]
searxng["SearXNG<br/>metasearch for grounding"]
end
end
subgraph llmHost[LLM server]
direction TB
subgraph ollamaStack[Local language processing]
ollama["Ollama<br/>translation / text embeddings"]
end
subgraph youtubeStack[YouTuber Bot-tan automation]
youtubeScripts["Bot-tan scripts<br/>Unity video automation"]
ardy["NVIDIA ARDY server<br/>AI real-time motion generation"]
end
subgraph voiceStack[Speech synthesis]
voicevox[VOICEVOX server]
end
end
end
jetsteamProxy --> repoApps
repoApps --> brain
brain <--> memory
repoApps <--> ollama
repoApps <--> searxng
youtubeScripts --> voicevox
youtubeScripts <--> ardy
flowchart LR
subgraph outputs[Project outputs]
bluesky[Bluesky Bot-tan]
nagi[Nagi Bot-tan]
youtube[YouTuber Bot-tan]
room[Bot-tan's Room]
portal[Bot-tan Portal]
end
subgraph services[Bot-tan services]
jetsteamProxy[JetsteamProxy]
repoApps["Bots / Nagi AppView<br/>and shared services"]
brain[Shared bot brain and RAG]
memory[(PostgreSQL)]
ollama[Ollama]
youtubeScripts["YouTuber Bot-tan scripts<br/>Unity automation"]
voicevox[VOICEVOX]
ardy[NVIDIA ARDY]
end
subgraph cloud[Platforms and cloud services]
atproto[AT Protocol / PDS / Jetstream]
gemini[Google Gemini]
youtubeApi[YouTube]
cloudflare[Cloudflare / public endpoints]
end
bluesky <--> atproto
nagi <--> cloudflare
room <--> cloudflare
portal <--> cloudflare
atproto <--> jetsteamProxy
jetsteamProxy --> repoApps
repoApps <--> atproto
cloudflare <--> repoApps
repoApps --> brain
brain <--> memory
repoApps <--> ollama
repoApps <--> gemini
room -.-> voicevox
youtubeScripts <--> gemini
youtubeScripts --> voicevox
youtubeScripts <--> ardy
youtubeScripts --> youtubeApi
youtubeApi --> youtube
Everyone is welcome. Feel free to open an issue or pull request, whether it is a bug report, documentation improvement, idea, translation, or code contribution. We take feedback seriously.
This is a personal project, and Suibari also has a life outside it and works at a very unhurried pace. A reply or review may therefore take time. Silence or delay is never meant negatively; your contribution is still sincerely appreciated.
The services behind Bot-tan run on personal cash. Sponsorship(in any way) supports not only this project, but Suibari's creative work as a whole.
If you think this feels like a valuable project to you, I would be delighted if you considered supporting it. Any amount is warmly welcome - or - if you feel more comfortable just sharing this project to your closest friends, it would be a huge help. Thank you so much.
This project is open source under the MIT License.
Nagi の自動判定方針と API 呼び出し回数は モデレーション仕様 を参照。





