Kage (布布管家) is a Discord bot built with Spring Boot WebFlux, R2DBC PostgreSQL, Redis, and Spring AI.
# Compile
mvn compile
# Compile tests
mvn test-compile
# Run all tests
mvn test
# Run specific test
mvn test -Dtest=ClassName
# Build (skip tests)
mvn package -DskipTests
# Build + Docker image
mvn clean package dockerfile:build -DskipTests@WebFluxTestremoved: Theorg.springframework.boot.test.autoconfigure.web.reactivepackage (including@WebFluxTestand@AutoConfigureWebTestClient) is gone fromspring-boot-test-autoconfigure. UseWebTestClient.bindToController()instead.WebTestClientNOT auto-configured: In SB4,WebTestClientis not auto-configured even with@SpringBootTest. Manual creation required viabindToServer()orbindToController().
- Uses
spring.ai.openai.*properties withbase-urlpointing to DeepSeek (OpenAI-compatible API) - Model:
deepseek-v4-flashwith thinking mode explicitly disabled viaextra-body - DO NOT use
spring-ai-starter-model-deepseek— it has bugs:DeepSeekChatModel.createRequest()doesn't serializereasoningContent, andDeepSeekChatOptionslacks athinkingtoggle. Usespring-ai-starter-model-openaiinstead. - Thinking mode is disabled because Spring AI cannot pass
reasoning_contentback during internal tool-call loops, causing 400 errors
- Java 17
- Reactive stack: WebFlux + R2DBC + Reactive Redis
- Discord integration: JDA 5.x
- Test framework: JUnit 5 (Jupiter)
- Build tool: Maven (wrapper included:
./mvnw) - Package:
run.runnable.kage
- CI/CD: GitHub Actions (
.github/workflows/deploy.yml) triggered on push tomain - Runtime: K3s cluster (deployment config:
k3s-deployment-prod.yaml) - Namespace:
996ninja - Docker registry: Ali Container Registry (registry.cn-hongkong.aliyuncs.com/runnable-run/kage)