Skip to content

Latest commit

 

History

History
191 lines (149 loc) · 9.33 KB

File metadata and controls

191 lines (149 loc) · 9.33 KB

AGENTS.md

Purpose

  • This repository provides a Flask-based SAM adapter for WEBKNOSSOS quick select.
  • The service exposes /healthz and /predictions/sam2_hiera_b.
  • It supports real SAM2 inference and a heuristic fallback mode.
  • The codebase is small, typed, and intentionally simple; keep changes minimal and local.

Repository Layout

  • app.py: Flask entrypoints, request handling, logging, HTTP error mapping.
  • config.py: environment-driven immutable settings.
  • parser.py: binary protocol parsing, validation, and mask serialization.
  • inference.py: inference orchestration, fallback behavior, normalization.
  • model.py: lazy SAM2 model loading and predictor integration.
  • tests/test_parser.py: unit tests for binary request parsing.
  • Dockerfile: runtime image and production command.
  • docker-compose.yml: standalone adapter stack.
  • docker-compose.webknossos.yml: WEBKNOSSOS overlay wiring.

Rules Files

  • No repo-level Cursor rules were found in .cursor/rules/.
  • No .cursorrules file was found.
  • No Copilot instructions were found at .github/copilot-instructions.md.
  • If any of those files are added later, treat them as authoritative additions to this document.

Environment Setup

  • Recommended local setup from the parent directory:
  • python -m venv .venv
  • . .venv/bin/activate
  • pip install -r sam_adaper/requirements.txt
  • Run package-based commands from /mnt/c/code, not from inside sam_adaper, when imports use sam_adaper.*.
  • GPU-backed SAM2 needs the sam2 dependency from requirements.txt and accessible model weights.
  • For smoke testing without model weights, set SAM_ADAPTER_INFERENCE_MODE=heuristic.

Build Commands

  • There is no separate Python build step such as setup.py, pyproject.toml, or wheel packaging.
  • Main container build:
  • docker build -t webknossos-sam-adapter -f sam_adaper/Dockerfile sam_adaper
  • Standalone compose build and run:
  • cd /mnt/c/code/sam_adaper && docker compose up -d --build
  • WEBKNOSSOS overlay build and run:
  • cd /mnt/c/code/sam_adaper && PUBLIC_HOST=your-host.example LETSENCRYPT_EMAIL=you@example.com docker compose -f ../webknossos/tools/hosting/docker-compose.yml -f docker-compose.webknossos.yml up -d --build
  • Production-style local server command from the repo root:
  • gunicorn -w 1 -b 0.0.0.0:8080 sam_adaper.app:app --timeout 300

Run Commands

  • Development server from /mnt/c/code:
  • python -m sam_adaper.app
  • Health check:
  • curl http://localhost:8080/healthz
  • Heuristic mode:
  • SAM_ADAPTER_INFERENCE_MODE=heuristic python -m sam_adaper.app
  • Force CPU if needed:
  • SAM_ADAPTER_FORCE_CPU=true python -m sam_adaper.app

Test Commands

  • The repository currently uses the standard library unittest framework.
  • Full test suite from /mnt/c/code:
  • python -m unittest discover -s sam_adaper/tests
  • Alternative explicit module invocation:
  • python -m unittest sam_adaper.tests.test_parser
  • Run a single test class:
  • python -m unittest sam_adaper.tests.test_parser.ParserTest
  • Run a single test method:
  • python -m unittest sam_adaper.tests.test_parser.ParserTest.test_parse_point_request
  • Current tests require installed dependencies such as numpy.
  • In the current environment, test discovery fails until dependencies are installed.

Lint And Formatting Commands

  • No linter is configured in the repository.
  • No formatter configuration file is present.
  • No type checker configuration file is present.
  • Do not assume ruff, flake8, black, isort, mypy, or pytest are project standards unless you add them intentionally.
  • If you need a lightweight validation step without changing tooling, use:
  • python -m compileall sam_adaper
  • If you introduce new tooling, update this file and keep the configuration checked into the repo.

Testing Expectations

  • Prefer small unit tests for parser and normalization logic.
  • Add regression tests when fixing protocol parsing or shape validation bugs.
  • Keep tests deterministic and CPU-only unless GPU coverage is explicitly needed.
  • For inference paths, isolate logic that can be tested without loading SAM2 weights.
  • Avoid introducing tests that require external services unless they are clearly marked integration tests.

Import Conventions

  • Use from __future__ import annotations at the top of Python modules, matching the existing files.
  • Group imports in this order: standard library, third-party, local package imports.
  • Separate import groups with a single blank line.
  • Prefer explicit relative imports within the package, e.g. from .parser import SamRequest.
  • Avoid wildcard imports.
  • Import only what the module actually uses.

Formatting Conventions

  • Follow existing PEP 8 style with 4-space indentation.
  • Keep functions and classes separated by a single blank line block consistent with the current files.
  • Use trailing commas and multi-line formatting when lines become long or readability improves.
  • Keep log statements readable; break argument lists across lines instead of cramming them into one line.
  • Preserve the repository's simple, standard-library-friendly style over heavy abstractions.

Type Conventions

  • Add type hints on public functions, methods, and important internal helpers.
  • Prefer modern built-in generics such as tuple[int, int] and dict[str, Any].
  • Use np.ndarray for array return types and parameters where shape-specific aliases are unnecessary.
  • Use dataclasses for immutable structured data such as Settings, SamRequest, and InferenceMetadata.
  • Prefer frozen=True dataclasses for configuration or metadata objects that should not mutate.
  • Use Any sparingly and only at library boundaries where third-party objects are effectively untyped.

Naming Conventions

  • Use snake_case for functions, methods, variables, and module names.
  • Use PascalCase for classes.
  • Use UPPER_SNAKE_CASE for module-level constants such as protocol codes and limits.
  • Choose names that reflect protocol semantics precisely, e.g. shape_x, interaction_type, used_fallback.
  • Keep helper names descriptive rather than abbreviated.

Error Handling

  • Represent client/request validation failures with domain-specific exceptions such as ParserError.
  • Represent model initialization failures with a dedicated exception such as ModelLoadError.
  • Convert known request problems into explicit HTTP responses with suitable status codes.
  • Log exceptions with context before returning 500 responses.
  • Re-raise exceptions when fallback is disabled rather than silently swallowing them.
  • Avoid broad except Exception unless it is guarding an outer boundary and either logs or re-raises.

Logging Guidelines

  • Use module-level loggers via logging.getLogger(__name__).
  • Keep logs operationally useful: include interaction type, shape, backend, fallback usage, and duration.
  • Log malformed requests at warning level.
  • Log unexpected inference failures with stack traces via logger.exception(...).
  • Avoid noisy debug logging unless it adds concrete troubleshooting value.

Flask And HTTP Patterns

  • Keep route handlers thin; delegate parsing and inference to dedicated modules.
  • Return flask.Response objects explicitly for binary and error responses.
  • Use jsonify(...) for JSON health/status payloads.
  • Preserve the existing endpoint paths; WEBKNOSSOS depends on them.
  • Do not change response MIME types casually; binary responses must remain application/octet-stream.

Parser And Protocol Guidelines

  • Treat the binary request protocol as strict and validate early.
  • Keep struct formats explicit and centralized.
  • Validate payload length, dimensions, prompt bounds, and supported element classes before processing.
  • Reject malformed inputs with clear error messages.
  • Preserve the current image memory layout assumptions unless the protocol changes.
  • When changing protocol behavior, update tests first or in the same change.

Numerical And Array Handling

  • Use NumPy vectorization where it keeps the code clear.
  • Preserve the repository's axis conventions carefully; the code intentionally transposes between (x, y, z) and (h, w) views.
  • Keep output masks as np.uint8 before serialization.
  • Validate shapes explicitly when crossing boundaries with external model outputs.
  • Prefer astype(..., copy=False) and contiguous conversion only where needed.

Model Integration Guidelines

  • Keep SAM2 loading lazy and thread-safe.
  • Do not load the model at import time.
  • Maintain the current lock-based initialization pattern when changing model setup.
  • Keep heuristic fallback available for smoke tests and degraded operation.
  • Avoid coupling testable business logic directly to GPU-only code.

Configuration Guidelines

  • Read runtime configuration from environment variables through Settings.
  • Keep defaults conservative and aligned with the current Docker and README examples.
  • Use small helpers like _get_bool for parsing env vars consistently.
  • Prefer adding new settings in config.py rather than scattering os.getenv(...) calls across modules.

Change Management

  • Keep edits small and focused; this is a compact service.
  • Prefer extending existing modules over creating new layers for minor behavior changes.
  • Update README.md, AGENTS.md, and tests when behavior or commands change.
  • If you add linting, typing, or test tooling, document exact commands here.
  • Preserve compatibility with the documented Docker and WEBKNOSSOS workflows.