docs(agent): update agent instruction

This commit is contained in:
MingxuanGame
2025-09-14 07:58:37 +00:00
parent c31c05d3f6
commit 7f1aee3d4a
2 changed files with 188 additions and 48 deletions

187
AGENTS.md Normal file
View File

@@ -0,0 +1,187 @@
# AGENTS.md
> Guidelines for using automation and AI agents (GitHub Copilot, dependency/CI bots, and in-repo runtime schedulers/workers) with the g0v0-server repository.
---
## API References
This project must stay compatible with the public osu! APIs. Use these references when adding or mapping endpoints:
- **v1 (legacy):** [https://github.com/ppy/osu-api/wiki](https://github.com/ppy/osu-api/wiki)
- **v2 (OpenAPI):** [https://osu.ppy.sh/docs/openapi.yaml](https://osu.ppy.sh/docs/openapi.yaml)
Any implementation in `app/router/v1/`, `app/router/v2/`, or `app/router/notification/` must match official endpoints from the corresponding specification above. Custom or experimental endpoints belong in `app/router/private/`.
---
## Agent Categories
Agents are allowed in three categories:
- **Code authoring / completion agents** (e.g. GitHub Copilot or other LLMs) — allowed **only** when a human maintainer reviews and approves the output.
- **Automated maintenance agents** (e.g. Dependabot, Renovate, pre-commit.ci) — allowed but must follow strict PR and CI policies.
- **Runtime / background agents** (schedulers, workers) — part of the product code; must follow lifecycle, concurrency, and idempotency conventions.
All changes produced or suggested by agents must comply with the rules below.
---
## Rules for All Agents
1. **Human review required.** Any code, configuration, or documentation generated by an AI or automation agent must be reviewed and approved by a human maintainer familiar with g0v0-server. Do not merge agent PRs without explicit human approval.
2. **Single-responsibility PRs.** Agent PRs must address one concern only (one feature, one bugfix, or one dependency update). Use Angular-style commit messages (e.g. `feat(api): add ...`).
3. **Lint & CI compliance.** Every PR (including agent-created ones) must pass `pyright`, `ruff`, `pre-commit` hooks, and the repository CI before merging. Include links to CI runs in the PR.
4. **Never commit secrets.** Agents must not add keys, passwords, tokens, or real `.env` values. If a suspected secret is detected, the agent must abort and notify a designated human.
5. **API location constraints.** Do not add new public endpoints under `app/router/v1` or `app/router/v2` unless the endpoints exist in the official v1/v2 specs. Custom or experimental endpoints must go under `app/router/private/`.
6. **Stable public contracts.** Avoid changing response schemas, route prefixes, or other public contracts without an approved migration plan and explicit compatibility notes in the PR.
---
## Copilot / LLM Usage
> Consolidated guidance for using GitHub Copilot and other LLM-based helpers with this repository.
### Key project structure (what you should know)
- **App entry:** `main.py` — FastAPI application with lifespan startup/shutdown orchestration (fetchers, GeoIP, schedulers, cache and health checks, Redis messaging, stats, achievements).
- **Routers:** `app/router/` contains route groups. Important routers exposed by the project include:
- `api_v1_router` (v1 endpoints)
- `api_v2_router` (v2 endpoints)
- `notification` routers (chat/notification subsystems)
- `auth_router` (authentication/token flows)
- `private_router` (internal or server-specific endpoints)
**Rules:** `v1/` and `v2/` must mirror the official APIs. Put internal-only or experimental endpoints under `app/router/private/`.
- **Models & DB helpers:**
- SQLModel/ORM models live in `app/models/`.
- DB access helpers and table-specific helpers live in `app/database/`.
- For model/schema changes, draft an Alembic migration and manually review the generated SQL and indexes before applying.
- **Services:** `app/service/` holds domain logic (e.g., user ranking calculation, caching helpers, notification/email logic). Heavy logic belongs in services rather than in route handlers.
- **Schedulers:** `app/scheduler/` contains scheduler starters; implement `start_*_scheduler()` and `stop_*_scheduler()` and register them in `main.py` lifespan handlers.
- **Caching & dependencies:** Use injected Redis dependencies from `app/dependencies/` and shared cache services (follow existing key naming conventions such as `user:{id}:...`).
- **Rust/native extensions:** `packages/msgpack_lazer_api` is a native MessagePack encoder/decoder. When changing native code, run `maturin develop -R` and validate compatibility with Python bindings.
### Practical playbooks (prompt patterns)
- **Add a v2 endpoint (correct):** Add files under `app/router/v2/`, export the router, implement async path operations using DB and injected caching dependencies. Do **not** add non-official endpoints to v1/v2.
- **Add an internal endpoint:** Add under `app/router/private/`; keep route handlers thin and move business logic into `app/service/`.
- **Add a background job:** Put pure job logic in `app/service/_job.py` (idempotent, retry-safe). Add scheduler start/stop functions in `app/scheduler/_scheduler.py`, and register them in the app lifespan.
- **DB schema changes:** Update SQLModel models in `app/models/`, run `alembic revision --autogenerate`, inspect the migration, and validate locally with `alembic upgrade head` before committing.
- **Cache writes & responses:** Use existing `UserResp` patterns and `UserCacheService` where applicable; use background tasks for asynchronous cache writes.
### Prompt guidance (what to include for LLMs/Copilot)
- Specify the exact file location and constraints (e.g. `Add an async endpoint under app/router/private/ ... DO NOT add to app/router/v1 or v2`).
- Ask for asynchronous handlers, dependency injection for DB/Redis, reuse of existing services/helpers, type annotations, and a minimal pytest skeleton.
- For native edits, require build instructions, ABI compatibility notes, and import validation steps.
### Conventions & quality expectations
- **Commit message style:** `type(scope): subject` (Angular-style).
- **Async-first:** Route handlers must be async; avoid blocking the event loop.
- **Separation of concerns:** Business logic should live in services, not inside route handlers.
- **Error handling:** Use `HTTPException` for client errors and structured logging for server-side issues.
- **Types & linting:** Aim for `pyright`-clean, `ruff`-clean code before requesting review.
- **Comments:** Avoid excessive inline comments. Add short, targeted comments to explain non-obvious or "magical" behavior.
### Human reviewer checklist
- Is the code async and non-blocking, with heavy logic in `app/service/`?
- Are DB and Redis dependencies injected via the project's dependency utilities?
- Are existing cache keys and services reused consistently?
- Are tests or test skeletons present and runnable?
- If models changed: is an Alembic migration drafted, reviewed, and applied locally?
- If native code changed: was `maturin develop -R` executed and validated?
- Do `pyright` and `ruff` pass locally?
### Merge checklist
- Run `uv sync` to install/update dependencies.
- Run `pre-commit` hooks and fix any failures.
- Run `pyright` and `ruff` locally and resolve issues.
- If native modules changed: run `maturin develop -R`.
- If DB migrations changed: run `alembic upgrade head` locally to validate.
### Tooling reference
```
uv sync
pre-commit install
pre-commit run --all-files
pyright
ruff .
maturin develop -R # when native modules changed
alembic revision --autogenerate -m "feat(db): ..."
alembic upgrade head
uvicorn main:app --reload --host 0.0.0.0 --port 8000
```
### PR scope guidance
- Keep PRs focused: one concern per PR (e.g., endpoint OR refactor, not both).
- Update README/config docs when adding new environment variables.
- If unsure about conventions, align with the closest existing service and leave a clarifying comment.
---
## Performance Tips
Below are practical, project-specific performance tips derived from this repository's architecture (FastAPI + SQLModel/SQLAlchemy, Redis caching, background schedulers, and a Rust-native messagepack module).
### Database
- **Select only required fields.** Fetch only the columns you need using `select(Model.col1, Model.col2)` instead of `select(Model)`.
```py
stmt = select(User.id, User.username).where(User.active == True)
rows = await session.execute(stmt)
```
- **Use **``** for existence checks.** This avoids loading full rows:
```py
from sqlalchemy import select, exists
exists_stmt = select(exists().where(User.id == some_id))
found = await session.scalar(exists_stmt)
```
- **Avoid N+1 queries.** Use relationship loading strategies (`selectinload`, `joinedload`) when you need related objects.
- **Batch operations.** For inserts/updates, use bulk or batched statements inside a single transaction rather than many small transactions.
- **Indexes & EXPLAIN.** Add indexes on frequently filtered columns and use `EXPLAIN ANALYZE` to inspect slow queries.
- **Cursor / keyset pagination.** Prefer keyset pagination for large result sets instead of `OFFSET`/`LIMIT` to avoid high-cost scans.
### Caching & Redis
- **Cache hot reads.** Use `UserCacheService` to cache heavy or frequently-requested responses and store compact serialized forms (e.g., messagepack via the native module).
- **Use pipelines and multi/exec.** When performing multiple Redis commands, pipeline them to reduce roundtrips.
- **Set appropriate TTLs.** Avoid never-expiring keys; choose TTLs that balance freshness and read amplification.
- **Prevent cache stampedes.** Use early recompute with jitter or distributed locks (Redis `SET NX` or a small lock library) to avoid many processes rebuilding the same cache.
- **Atomic operations with Lua.** For complex multi-step Redis changes, consider a Lua script to keep operations atomic and fast.
### Background & Long-running Tasks
- **BackgroundTasks for lightweight work.** FastAPI's `BackgroundTasks` is fine for quick follow-up work (send email, async cache write). For heavy or long tasks, use a scheduler/worker (e.g., a dedicated async worker or job queue).
- **Use schedulers or workers for heavy jobs.** For expensive recalculations, use the repository's `app/scheduler/` pattern or an external worker system. Keep request handlers responsive — return quickly and delegate.
- **Throttling & batching.** When processing many items, batch them and apply concurrency limits (semaphore) to avoid saturating DB/Redis.
### API & Response Performance
- **Compress large payloads.** Enable gzip/deflate for large JSON responses