Files
llm-connect/.claude/rules/architecture.md
Bernd Worsch d71f4114d1 feat: WP-0001 foundation + WP-0002 core extensions
WP-0001 — Foundation & GAAF Baseline
- SCOPE.md, ARCHITECTURE-LAYERS.md, contracts/ tree
- .claude/rules/ stubs filled (architecture, stack, boundary)
- 57 tests (pytest), pyproject.toml with ruff+mypy, CI workflow

WP-0002 — Core Extensions (FR-4 + FR-3)
- FR-4: BudgetTracker (thread-safe) + LLMBudgetExceededError +
  optional RunConfig.budget_tracker + enforcement in all adapters
- FR-3: async_execute_prompt on LLMAdapter ABC (asyncio.to_thread
  fallback) + native asyncio.create_subprocess_exec in ClaudeCodeAdapter

81 tests passing.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-01 22:24:14 +00:00

2.2 KiB

Architecture

llm-connect is structured as a GAAF-2026 layered library. See ARCHITECTURE-LAYERS.md for the full layer map and scorecard.

Layer summary

Core (frozen after v1)
  LLMAdapter ABC          adapter.py
  RunConfig / LLMResponse models.py
  LLMError hierarchy      exceptions.py
  MockLLMAdapter          adapter.py   ← test primitive, belongs with Core

Functional (evolvable, independently shippable)
  OpenAIAdapter           openai.py
  GeminiAdapter           gemini.py
  OpenRouterAdapter       openrouter.py
  ClaudeCodeAdapter       claude_code.py
  EmbeddingAdapter ABC    embedding_adapter.py
  OpenAICompatibleEmbeddingAdapter  embedding_openai.py
  EmbeddingCache          embedding_cache.py
  create_adapter()        factory.py
  create_embedding_adapter()  embedding_factory.py
  _token_estimator        _token_estimator.py
  similarity utilities    similarity.py

Configuration (user-controlled declarative state)
  resolve_llm() chain     toml_config.py   ← 7-level TOML priority chain
  LLMConfig / load_config config.py
  _http shared utility    _http.py         ← also used by Functional adapters

Dependency rule

Core ← Functional ← Configuration
No upward dependencies. _http.py is consumed by Functional only.

Key design decisions

API key resolution (config.resolve_api_key): three-step chain — explicit argument → environment variable → plaintext key file in project root. Adapters raise LLMConfigurationError at construction time if no key is found (except ClaudeCodeAdapter which needs no key).

TOML config chain (toml_config.resolve_llm): 7 priority levels allow per-project and per-user LLM preferences. Currently defaults to markitect app_name for backward compatibility — consumers pass their own app_name.

Factory pattern (factory.create_adapter): lazy imports prevent pulling all provider SDKs at module load. Add a new provider by registering its FQN in _PROVIDERS.

ClaudeCodeAdapter subprocess model: prompt is piped via stdin (not CLI arg) to avoid shell argument length limits on large prompts (>30 KB).

Retry logic: OpenAIAdapter and OpenRouterAdapter retry on 429 and 5xx with exponential backoff. GeminiAdapter does not (rate-limit handling deferred).