This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is a web application showcasing the Align AI Decision Maker library for making human-value aligned decisions in ethical scenarios. The app is built with Python using the Trame framework for web UI and integrates with HuggingFace models via the align-system library.
# Install with development dependencies
poetry install --with dev
pre-commit install
# Set required environment variable for HuggingFace models
export HF_TOKEN=<your_huggingface_token># Start the web server (default port 8080)
poetry run align-app
# Custom port/host
poetry run align-app --port 8081 --host 0.0.0.0# Run all tests
poetry run pytest
# Run end-to-end tests
poetry run pytest tests/e2e/ -v
# Run e2e tests with full output
poetry run pytest tests/e2e/ -xvs
# Lint and format code
ruff check --fix
ruff format
# Type checking
mypy align_app/
# Run all pre-commit hooks
pre-commit run --all-files
# Fix codespell issues
codespell -w-
align_app/app/: Web application framework using Tramecore.py: Main AlignApp class and UI componentsmain.py: Application entry pointui.py: User interface layout and interactionsprompt.py: Prompt management for LLM interactions
-
align_app/adm/: AI Decision Maker integrationadm_core.py: Core ADM functionality and model managementdecider.py: Decision logic and scenario processingmultiprocess_decider.py: Multi-process decision handlinginput_output_files/: Training data and scenarios (NAACL24, OpinionQA datasets)
-
align_app/utils/: Shared utilities
align-system: Core AI decision making library (git dependency)trame: Web framework for Python applicationshydra-core/omegaconf: Configuration management- HuggingFace ecosystem for LLM backends
The app supports various LLM backbones through HuggingFace transformers. Models are cached locally after first download. ADM types include different decision-making algorithms that can be configured via the UI.
- User selects ADM type, LLM backbone, alignment targets, and scenario via web UI
- Parameters are processed through
adm_core.pyusing Hydra configuration - Decision is made using the align-system library
- Result with justification is returned to the UI for comparison with previous decisions
- Functional Core (
*_core.py) - Pure functions on immutable data structures- Example:
add_run(data: Runs, run: Run) -> Runs
- Example:
- Registry (
*_registry.py) - State management via closures withnonlocal data- Calls functional core, captures returned state
- State Adapter (
*_state_adapter.py) - Trame UI bridge- Controllers trigger registry, sync to reactive state
Flow: UI → Adapter → Registry → Core → new data → Registry → Adapter → UI
- Immutable data:
@dataclass(frozen=True),replace()instead of mutation - Pure transformations: return new collections, no in-place modifications
- Separation: pure logic in
*_core.py, side effects in registry/adapter
E2e tests use Playwright to test the full application stack. The test infrastructure captures all backend server logs, prints, and errors:
- Backend stdout and stderr are captured in real-time
- All logs are displayed after each test (both passing and failing)
- Backend errors and tracebacks are included in test failure reports
- Add
print()statements in backend code to debug during e2e tests
codespell: Spell checking (excludes .json files and CHANGELOG.md)ruff: Code linting and formattingmypy: Type checking with PyYAML types support
- Run ruff format after changes
For CSS/layout issues in Trame/Vuetify apps, use Playwright MCP to inspect the live DOM:
-
Start the server (restart after code changes):
poetry run align-app --server
-
Navigate and interact:
- Use
mcp__playwright__browser_navigateto openhttp://localhost:8080 - Use
mcp__playwright__browser_clickto interact with elements - Use
mcp__playwright__browser_take_screenshotto capture visual state
- Use
-
Inspect computed styles:
// Use mcp__playwright__browser_evaluate to inspect DOM () => { const element = document.querySelector('.your-selector'); const style = getComputedStyle(element); return { width: element.offsetWidth, computedWidth: style.width, minWidth: style.minWidth, flexBasis: style.flexBasis, flexGrow: style.flexGrow, }; }
-
Compare elements: When alignment is off, compare computed styles between elements that should match (e.g., title row vs content row columns).
-
Common Vuetify gotchas:
- VCol with empty content may collapse despite explicit
width- addmin-widthto prevent - Vuetify's default
max-width: 100%on expansion panels may need override flex-basis: 0withflex-growmakesmax-contentcalculation return 0
- VCol with empty content may collapse despite explicit
- ALWAYS do not add descriptive comments
- ALWAYS run ruff format after changes