AOP Builder is a monorepo for document-based adverse outcome pathway analysis. It provides a Vue frontend and a Docker Compose backend that can:
- upload and manage document collections
- preprocess and chunk documents
- score chunk relevance
- extract causal relationships with an OpenAI-compatible chat model
- enrich extracted entities against OLS4 and, optionally, an AOP-Wiki MCP service
- review raw and enriched graphs in the browser
apps/ai-client: Vue 3 frontend served by Vite for development or Nginx for container buildsapps/ai-core: FastAPI services, workers, and Compose filesscripts: root-level helper scripts that keep commands consistent from the monorepo root.env.example: reproducible local configuration template with placeholder secrets only
Install:
- Docker Engine or Docker Desktop with Docker Compose v2
- Node.js 20+ and npm
- Git
Recommended:
- NVIDIA Container Toolkit if you want GPU-backed Ollama inference through Docker
- Python 3.11+ if you want to debug individual backend services outside Docker
The default local setup pulls qwen3:14b into an Ollama container. Use a smaller model such as qwen3:8b if local hardware is constrained.
- Clone the repository.
git clone <repo-url>
cd aop-builder- Create a local environment file.
cp .env.example .env- Replace placeholder values in
.env.
Use .env.example as the source of truth for available settings. At minimum, replace the local database password and JWT secret placeholders before starting the stack.
- Install frontend dependencies.
cd apps/ai-client
npm install
cd ../..- Start the backend.
./scripts/core-up.shThe first run can take time because the llm_init container pulls the configured Ollama model into the ollama_data volume.
- Start the frontend.
./scripts/client-dev.sh- Open the Vite URL printed by the frontend, usually
http://localhost:5173.
The default backend gateway is exposed on http://localhost:8005, matching the example environment and the Vite proxy in apps/ai-client/vite.config.ts.
The repository does not build the AOP MCP image itself. To keep the stack reproducible from this repo alone, the aop-mcp service is disabled by default.
To enable it, make sure the MCP image referenced in .env exists locally or is pullable, set the MCP base URL in .env, then run:
COMPOSE_PROFILES=aop-mcp ./scripts/core-up.shWithout that profile, enrichment still runs with OLS4 normalization and skips AOP-Wiki MCP lookups.
Start backend with local builds:
./scripts/core-up.shStop backend:
./scripts/core-down.shBuild frontend:
./scripts/client-build.shRun frontend dev server:
./scripts/client-dev.shReport stale sessions without changing data:
./scripts/cleanup-stale-sessions.sh --max-age-minutes 15Cancel stale sessions after reviewing the dry-run output:
./scripts/cleanup-stale-sessions.sh --apply --max-age-minutes 15Backend deployment uses apps/ai-core/docker-compose-deploy.yml, which references prebuilt GHCR images instead of building from local source.
- Build and publish images through the root GitHub Actions workflow in
.github/workflows/docker.yml, or publish equivalent images. - Copy
.env.exampleto.envon the deployment host and replace all required placeholders. - Set the deploy image registry and tag in
.envto match the published backend images. - Start the deploy stack:
./scripts/core-deploy.shThe deploy compose file binds service ports to 127.0.0.1 by default. Put a reverse proxy in front of public_gateway if the API should be reachable from another host.
Notes:
- The frontend image is built by CI, but it is not currently included in
docker-compose-deploy.yml. Deploy it separately or add it behind your reverse proxy. aop-mcpremains optional in deploy as well. UseCOMPOSE_PROFILES=aop-mcp ./scripts/core-deploy.shonly when the MCP image is available.- The workflow uses the built-in GitHub token with package write permissions; no personal access token is required for publishing to the same GitHub organization/user package namespace.
Tracked files should contain placeholders only. The root .env file is ignored by git and should never be committed.
Before publishing, run:
git status --short
rg -n --hidden -g '!.git/**' -g '!apps/ai-client/package-lock.json' \
'(api[_-]?key|secret|password|token|bearer|BEGIN (RSA|OPENSSH|PRIVATE) KEY)' .
git grep -n -I -E \
'(sk-[A-Za-z0-9_-]{20,}|ghp_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|AIza[0-9A-Za-z_-]{20,}|AKIA[0-9A-Z]{16}|BEGIN (RSA|OPENSSH|PRIVATE) KEY)' \
$(git rev-list --all) -- .This review found no high-confidence API keys, tokens, or private keys in the current tree or history. History does contain old demo placeholders such as myuser, mypassword, and replace-with-openai-key; those are not real secrets but they may still look noisy to automated scanners.
cp .env.example .envThen replace the required placeholders documented in .env.example.
Check:
- backend containers are running with
cd apps/ai-core && docker compose --env-file ../../.env ps - the gateway port matches the Vite proxy
- browser requests are going to
/auth,/collections, and/sessions
Inspect logs:
cd apps/ai-core
docker compose --env-file ../../.env logs public_gateway
docker compose --env-file ../../.env logs cer_serviceCheck:
- Docker has enough disk space for the selected Ollama model
- GPU support is available if
gpus: allis required on your host - the selected model tags are available to Ollama
- the CER API base URL points at the in-stack Ollama service for the default local path
Common local ports:
5173: Vite8005: public gateway11434: Ollama5432: Postgres27017: MongoDB5672and15672: RabbitMQ
Stop the conflicting process or adjust the mapped ports in .env and apps/ai-core/docker-compose.yml.