- This file guides agentic coding assistants working in this repo.
- Follow instructions in more specific
AGENTS.mdfiles if present. - Keep changes minimal and focused.
- Python 3.12+, FastAPI, aio-pika (RabbitMQ), redis.asyncio, OpenAI API.
- Package manager:
uv. - Tests:
pytest+pytest-asyncio. - Lint/format:
ruff; typing:mypy.
llmtrigger/main packagellmtrigger/api/FastAPI routes (/rules,/history,/test)llmtrigger/core/config + loggingllmtrigger/engine/traditional + LLM logicllmtrigger/engine/llm/prompts + parsingllmtrigger/messaging/RabbitMQ consumersllmtrigger/notification/dispatch + channelsllmtrigger/storage/Redis persistencetests/unit/unit teststests/integration/integration tests
- Install deps (dev):
uv sync --dev - Start infra:
docker-compose up -d redis rabbitmq - Stop infra:
docker-compose down - Copy env:
cp .env.example .env - Fill
REDIS_URL,RABBITMQ_URL,OPENAI_API_KEY
- API (dev):
uv run uvicorn llmtrigger.api.app:app --reload - Worker:
uv run python -m llmtrigger.worker - Optional: set
LOG_LEVEL=DEBUGfor verbose logs
- All tests:
uv run pytest - Single file:
uv run pytest tests/unit/test_expression.py - Single test:
uv run pytest tests/unit/test_expression.py::test_evaluate_simple_expression - Markers: use
@pytest.mark.asynciofor async tests - Coverage:
uv run pytest --cov=llmtrigger --cov-report=html
- Lint:
uv run ruff check llmtrigger/ - Format:
uv run ruff format llmtrigger/ - Type check:
uv run mypy llmtrigger/ - Run format before lint when unsure
- Indentation: 4 spaces, no tabs.
- Formatting: follow PEP 8; use
ruff format. - Imports: absolute imports preferred; keep sorted (isort compatible).
- Avoid wildcard imports.
- Keep functions small and single-purpose.
- Avoid unnecessary abstraction or cleverness.
- Type hints required for public functions, methods, and class attributes.
- Use explicit return types for public functions.
- Prefer
typingprimitives (list,dict,tuple) with generics. - Use
Optional[T]/T | Noneconsistently. - Avoid
Anyunless unavoidable; document why.
- Files/modules:
snake_case.py - Classes:
PascalCase - Functions/variables:
snake_case - Constants:
UPPER_SNAKE_CASE - Avoid one-letter names except for tight scopes.
- Use descriptive parameter names for external APIs.
- Prefer async APIs for IO (
aio-pika,redis.asyncio). - Do not block the event loop with sync IO or heavy CPU work.
- Use
awaitfor network/database calls. - Use
asyncio.create_taskcarefully; track lifecycle. - Tests for async code must use
@pytest.mark.asyncio.
- Never hardcode secrets or URLs.
- Read settings from
llmtrigger.core.config.settings. - Add new settings to config module +
.env.example. - Keep defaults sensible for local development.
- Raise specific exceptions; avoid bare
Exception. - API layer: use FastAPI
HTTPExceptionfor client errors. - Worker/consumer: catch exceptions to avoid crashing loop.
- Log with
structlogviallmtrigger.corelogger. - Include context fields (rule_id, event_id) when logging.
- Keep prompts in
llmtrigger/engine/llm/. - Avoid leaking secrets into prompts.
- Parse model responses defensively; validate outputs.
- Redis access should be async and pooled.
- RabbitMQ consumers must ack/nack appropriately.
- Handle transient network failures with retries/backoff.
- Keep tests deterministic; avoid network calls without mocks.
- Use fixtures where possible; prefer focused unit tests.
- Mark integration tests clearly under
tests/integration. - Prefer testing behavior over implementation details.
- Update validation in
models/rule.py. - Add routing in
llmtrigger/engine/router.py. - Ensure any new config fields are documented.
- Add a new module under
llmtrigger/notification/channels/. - Implement
BaseNotificationChannel.send. - Register in
NotifyTargetTypeand dispatcher. - Add unit tests for channel behavior when feasible.
- Prefer Chinese (中文) for communication and PR summaries.
- Code comments/docstrings should be English.
- Use absolute paths in tool calls.
- Verify working directory with
pwdif needed. - If imports fail, run
uv sync --dev. - Do not create extra docs unless requested.
- Avoid touching unrelated files.
- Commit messages: sentence-case English or Chinese.
- PRs should include summary and test commands run.
- Mention any config changes or new env vars.
- Do not amend commits unless explicitly requested.
REDIS_URLdefaultredis://localhost:6379/0RABBITMQ_URLdefaultamqp://guest:guest@localhost:5672/OPENAI_API_KEYrequired for LLM featuresOPENAI_MODELdefaultgpt-4-turbo-previewLOG_LEVELdefaultINFO
- Keep docstrings short and in English.
- Update README or docs only when requested.
- Avoid inline comments unless needed for clarity.
- No
.cursor/rules,.cursorrules, or Copilot instructions found.