Files
astrbot_plugin_qq_group_dai…/.github/copilot-instructions.md
T

4.2 KiB

Project: astrbot_plugin_qq_group_daily_analysis

AstrBot plugin for daily QQ/Telegram/Discord group chat analysis & summarization using LLM.

Architecture: DDD + Clean Architecture

src/
├── domain/              ← Pure business logic, NO infrastructure deps
│   ├── entities/        ← Aggregates (AnalysisTask, IncrementalState)
│   ├── value_objects/   ← Immutable (UnifiedMessage, UnifiedGroup, PlatformCapabilities)
│   ├── models/          ← DTOs (SummaryTopic, UserTitle, GoldenQuote)
│   ├── services/        ← Stateless domain services
│   ├── repositories/    ← ABC interfaces (I* prefix)
│   └── exceptions.py    ← DomainException hierarchy
├── application/         ← Use cases, orchestrates domain + infra
│   ├── services/        ← AnalysisApplicationService, MessageProcessingService
│   └── commands/
├── infrastructure/      ← Concrete impls of domain interfaces
│   ├── analysis/        ← LLMAnalyzer, BaseAnalyzer, etc.
│   ├── config/          ← ConfigManager
│   ├── messaging/       ← Cross-platform message dispatch
│   ├── persistence/     ← History, incremental store, registries
│   ├── platform/        ← PlatformAdapter ABC + adapters per platform
│   ├── reporting/       ← Templates, dispatcher, generators
│   ├── scheduler/       ← Auto-scheduling
│   └── visualization/
├── shared/              ← constants.py, trace_context.py
└── utils/               ← logger.py, resilience.py

Naming Conventions

  • Files: snake_case (analysis_application_service.py)
  • Classes: PascalCase (ConfigManager, AnalysisTask)
  • Functions/methods: snake_case (analyze_topics(), _format_msg())
  • Private methods: _ prefix (_get_group())
  • Constants: UPPER_SNAKE_CASE (PLUGIN_NAME, SUPPORTED_PLATFORMS)
  • Abstract interfaces: I prefix (IAnalysisProvider, IMessageRepository)
  • Test files: test_ + snake_case (test_message_processing_service.py)
  • Logger: logger singleton from src.utils.logger

Imports

  • Relative imports (.) inside src/:
    from ..value_objects.unified_message import UnifiedMessage
    from ...utils.logger import logger
    
  • Absolute imports for AstrBot API:
    from astrbot.api.event import filter, AstrMessageEvent
    from astrbot.api.star import Context, Star, register
    
  • No wildcard imports. Prefer relative for internal, absolute for external.

Type Hints

  • Use str | None, list[dict], dict[str, int] (Python 3.10+ union syntax)
  • Use TypedDict for structured dicts
  • Use @dataclass(frozen=True) for value objects
  • Use collections.abc for abstract types (AsyncGenerator, Callable)

Docstrings (Chinese)

def method(self, arg: str) -> Result:
    """
    方法描述。

    Args:
        arg: 参数说明

    Returns:
        返回值说明

    Raises:
        SomeError: 异常说明
    """

Error Handling

  • Domain exceptions in src/domain/exceptions.py: DomainExceptionAnalysisException / PlatformException
  • Always log errors with exc_info=True: logger.error(f"msg", exc_info=True)
  • Use CircuitBreaker from src/utils/resilience.py for LLM calls

Logging

from src.utils.logger import logger
logger.info(f"[模块] 描述")
logger.error(f"[模块] 描述", exc_info=True)

AstrBot Plugin Patterns

  • Plugin class extends Star, registered with @register(...)
  • Commands: @filter.command("name", alias={"alt"}) on async methods
  • Admin-only: @filter.permission_type(filter.PermissionType.ADMIN)
  • Responses: yield event.plain_result(...) or yield event.chain_result([...])
  • Suppress LLM: event.should_call_llm(True)
  • Config: _conf_schema.json with groups; access via self.config["key"]

DI Pattern

Manual constructor injection in GroupDailyAnalysis.__init__; no DI container.

Platform Abstraction

PlatformAdapter ABC combines 4 domain interfaces. Concrete adapters in infrastructure/platform/adapters/. Cross-platform messages normalized to UnifiedMessage (frozen dataclass).