CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Build Commands

# Full build with tests
mvn clean install

# Build without tests (quick)
mvn clean install -DskipTests

# Run all tests
mvn test

# Run a single test class
mvn test -pl mayfly-core -Dtest=ModelInstanceTest

# Run a single test method
mvn test -pl mayfly-adapter -Dtest=DeepSeekModelAdapterTest#testCreateChatModel

# Run mutation tests (PIT)
mvn org.pitest:pitest-maven:mutationCoverage

# Build Docker image
docker build -t mayfly .

# Run with Docker Compose
docker compose up

Project Architecture

Mayfly is a multi-module Maven project (Java 17, Spring Boot 3.2, Spring AI 1.0-M6) providing enterprise-grade model routing for Spring AI.

Module Dependency Chain

mayfly-core (interfaces & domain models)
  → mayfly-router (routing strategies)
  → mayfly-loadbalancer (load balancing)
  → mayfly-failover (failover/retry)
  → mayfly-circuitbreaker (Resilience4j-based)
  → mayfly-monitor (Micrometer metrics)
  → mayfly-adapter (model implementations)
  → mayfly-spring-boot-starter (auto-configuration)
  → mayfly-demo (example application)

Core Interfaces (mayfly-core)

  • ModelRouter: Unified entry point (chat(), stream(), async())
  • ModelRegistry: Manages available model instances, supports tag-based filtering
  • ModelConfig/ModelInstance: Configuration vs runtime state separation (Config POJO + Instance with health/cooldown/activeRequests)
  • HealthStatus: Enum with HEALTHY/UNHEALTHY/COOLDOWN states

Routing & Load Balancing

  • RouterStrategy (mayfly-router): 3 implementations — FixedRouterStrategy (always same model), WeightedRouterStrategy (weight-based), RuleBasedRouterStrategy (SpEL expression rules with priority ordering)
  • LoadBalancer (mayfly-loadbalancer): RoundRobinLoadBalancer and WeightedRoundRobinLoadBalancer

Enterprise Features

  • FailoverHandler (mayfly-failover): Marks failed models as COOLDOWN, selects backup candidates, supports retryable exception class matching
  • CircuitBreakerManager (mayfly-circuitbreaker): Wraps Resilience4j CircuitBreaker + RateLimiter per model
  • MetricsCollector (mayfly-monitor): Interface + MicrometerMetricsCollector (real) + NoOpMetricsCollector (fallback); covers call success/failure, failover, streaming chunks/latency

Model Adapters (mayfly-adapter)

Each adapter follows a uniform pattern: a ModelAdapter factory + inner ChatModel implementation + inner HttpClient implementation. Currently supports:

  • ZhiPu (GLM-4) — custom API, @Component registered via component scan
  • Tongyi (Qwen) — custom API
  • DeepSeek — OpenAI-compatible API
  • OpenAI — standard API
  • Claude — Anthropic API
  • Wenxin — Baidu API
  • Xinghuo — iFlytek API

BaseHttpClient provides shared RestTemplate (sync) and WebClient (streaming) implementations. BaseStreamingChatModel provides reusable SSE parsing for OpenAI-compatible models.

Auto-Configuration (mayfly-spring-boot-starter)

  • MayflyProperties binds mayfly.* YAML config
  • MayflyAutoConfiguration wires all beans, strategy-selection via @ConditionalOnProperty
  • DefaultModelRouter orchestrates: select → circuit-breaker → call → failover → retry
  • DefaultModelRegistry reads config from properties, delegates ChatModel creation to ModelAdapter

Testing Patterns

  • Interface contract tests (e.g., ModelAdapterInterfaceContractTest, HttpClientInterfaceContractTest) validate all implementations enforce the same contract
  • WireMock tests for HTTP layer (BaseHttpClientWireMockTest)
  • PIT mutation testing with 80% mutation/coverage thresholds
  • Streaming-specific tests for each streaming-capable adapter
  • Exception/boundary tests for edge cases (nulls, empty lists, concurrent access)
  • Integration test (MayflyFullIntegrationTest) verifies the complete routing pipeline