Spaces:
Running
Running
File size: 20,700 Bytes
eb60b6b 336e2c2 2f1e7ff 336e2c2 f21ebe0 336e2c2 eb60b6b 336e2c2 eb60b6b 336e2c2 eb60b6b 336e2c2 eb60b6b 336e2c2 eb60b6b 336e2c2 2f1e7ff f21ebe0 336e2c2 eb60b6b 336e2c2 5583f46 336e2c2 5583f46 336e2c2 eb60b6b 5583f46 09ca6cf 7135ba5 2f1e7ff 7135ba5 09ca6cf 2f1e7ff 09ca6cf 2f1e7ff 89e57b7 2f1e7ff 89e57b7 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 | # Agent Deployment Guide for Hugging Face Space
This document serves as the guide and best practices for automated agents deploying and maintaining BrainAPI on Hugging Face Spaces.
## 1. Deployment Configuration
### Target Space
- **Profile:** `Leon4gr45`
- **Space:** `brain`
- **Full Identifier:** `Leon4gr45/brain`
- **Frontend Port:** `7860` (mandatory for Hugging Face Spaces)
### Deployment Method
- **Docker SDK** (`Dockerfile`)
### HF Token
- Always pass/read the HF access token from the environment (`HF_TOKEN` environment variable). Never hardcode secrets or token strings in repository files.
### Required Files
- `Dockerfile` (exposing nginx on port `7860`; uvicorn stays internal on port `8000`)
- `README.md` with Hugging Face YAML frontmatter:
```yaml
---
title: BrainAPI
sdk: docker
app_port: 7860
---
```
- `.hfignore` to exclude `.git`, `.venv`, `node_modules`, and cache directories
- `Agent.md` (this file)
---
## 2. API Exposure and Documentation
### Mandatory Endpoints
- **`/health`**
- Method: GET
- Purpose: Returns HTTP 200 when the app is ready. Required for Hugging Face Space liveness.
- Request: None
- Response:
```json
{
"status": "ok",
"service": "brainapi",
"version": "2.19.0-dev"
}
```
- **`/api-docs`**
- Method: GET
- Purpose: Redirects/Exposes full OpenAPI / Swagger documentation for all endpoints. Reachable at `https://Leon4gr45-brain.hf.space/api-docs`.
- Response: HTTP 307 redirect to `/docs` or Swagger UI HTML page.
- **`/`**
- Method: GET
- Purpose: Redirects public root visits to `/console/`.
- Response: HTTP 307 redirect to `/console/`.
---
## 3. Deployment Workflow & Ongoing Best Practices
1. **Pre-flight Check:**
Clean up non-project or stale files in the target Hugging Face Space using `huggingface_hub` Python API.
2. **Deploy Command:**
```bash
python deploy/hf_space.py stage --output /tmp/brainapi-hf-source
# Inspect/build the staged tree before uploading that same Git revision.
python deploy/hf_space.py upload --revision HEAD
```
This stages the complete committed Git tree, checks every required Docker
input, and verifies the uploaded Space files against the staged content.
Run it from the BrainAPI checkout with `huggingface_hub` installed and
`HF_TOKEN` set through secure environment settings. Do not upload a manually
selected list of changed files. The readiness wrapper must remain in the
Space repository alongside `scripts/preload_ollama_models.sh`.
3. **Log Monitoring:**
- **Build Logs (SSE):**
```bash
curl -N -H "Authorization: Bearer $HF_TOKEN" "https://huggingface.co/api/spaces/Leon4gr45/brain/logs/build"
```
- **Run Logs (SSE):**
```bash
curl -N -H "Authorization: Bearer $HF_TOKEN" "https://huggingface.co/api/spaces/Leon4gr45/brain/logs/run"
```
4. **Iterative Debugging:**
Inspect build and run logs for missing dependencies, port binding issues, or startup exceptions. Modify codebase accordingly, redeploy, and monitor until the Space reaches `RUNNING` status and responds to `/health` and `/api-docs`.
### Functional Endpoints
### /retrieve/context
- **Method:** POST
- **Purpose:** Retrieve an entity's contextual information based on a given text, generating triples and passages.
- **Authentication:** Requires `BrainPAT` header or Bearer token verified by the central AuthService.
- **Request (JSON):**
- `text` (str, required): The text to search context for.
- `brain_id` (str, optional, default: `"default"`): The brain/workspace identifier to query.
- `historical_limit` (int, optional, default: `10`)
- `max_facts` (int, optional, default: `40`, min: `0`)
- `max_passages` (int, optional, default: `8`)
- `apply_fact_filter` (bool, optional, default: `true`)
- `use_ppr` (bool, optional, default: `true`)
- `sufficiency_retry` (bool, optional, default: `false`)
- `profile_stages` (bool, optional, default: `false`)
- `cross_event_bridges` (int, optional, default: `3`, min: `0`)
```json
{
"text": "Identify memory leaks in Python",
"brain_id": "default",
"historical_limit": 10,
"max_facts": 40,
"max_passages": 8,
"apply_fact_filter": true,
"use_ppr": true,
"sufficiency_retry": false,
"profile_stages": false,
"cross_event_bridges": 3
}
```
- **Response (JSON):**
```json
{
"text_context": "Found 3 passages and 10 triples related to the query...",
"triples": [
{
"identified_entity": "memory_leak",
"triple": [
{"id": "python", "label": "Language", "properties": {"name": "Python"}},
{"id": "causes", "type": "CAUSES", "properties": {}},
{"id": "memory_leak", "label": "Issue", "properties": {"name": "Memory Leak"}}
],
"source_chunk_ids": ["chunk-123"]
}
],
"historical_context": ["Previous discussions about memory profiling..."],
"source_passages": ["Python's garbage collector sometimes misses reference cycles..."],
"graph_session_ids": ["sess-456"],
"temporal_conflicts": [],
"paths": [],
"topics": [{"topic": "performance", "weight": 0.8}],
"stage_timings": {"retrieval": 0.15, "formatting": 0.02}
}
```
### /retrieve/search
- **Method:** POST (Canonical) / GET (Compatibility)
- **Purpose:** Execute a ranked search across passages, entities, events, communities, and plugins with optional re-ranking.
- **Authentication:** Requires `BrainPAT` header or Bearer token verified by the central AuthService.
- **Request (POST JSON or GET Query Params):**
- `query` (str, required): The search query.
- `brain_id` (str, optional, default: `"default"`): The brain identifier to query.
- `k` (int, optional, default: `10`, range: `1-200`): Number of hits to return.
- `channels` (List[str], optional, default: `["passages"]`): Channels to search. Allowed channels include `passages`, `entities`, `events`, `communities`, and/or `plugin:<name>`.
- `node_labels` (List[str], optional, default: `null`): Node labels to filter the entities channel.
- `community_labels` (List[str], optional, default: `null`): Hub labels for the communities channel.
- `expand` (str, optional, default: `"none"`): Allowed values: `"none"`, `"neighbors"`. Optional 1-hop expansion from graph channel seeds.
- `fusion` (str, optional, default: `null`): Fusion override. Allowed values: `"rrf"`, `"cc"`.
- `fusion_alpha` (float, optional, default: `null`, range: `0.0-1.0`)
- `rerank` (str, optional, default: `null`): `none` or `plugin:<name>`. Unknown plugin names return 400.
- `mode` (str, optional, default: `"default"`): Allowed values: `"default"`, `"catalog"`.
- `profile_stages` (bool, optional, default: `false`)
- `extras` (Dict[str, str], optional, default: `null`)
- `target` (str, optional, default: `null`): Optional USER uuid or id for query-gated rerank of retrieved hits.
```json
{
"query": "hello world",
"brain_id": "default",
"k": 10,
"channels": ["passages", "entities"],
"node_labels": ["Document", "Author"],
"community_labels": ["Tech"],
"expand": "none",
"fusion": "rrf",
"fusion_alpha": 0.5,
"rerank": "plugin:cohere",
"mode": "default",
"profile_stages": false,
"extras": {},
"target": "user-123"
}
```
- **Response (JSON):**
```json
{
"hits": [
{
"id": "hit-789",
"channel": "passages",
"score": 0.95,
"scores": {"dense": 0.95, "bm25": 4.2, "rrf": 0.033},
"snippet": "Hello World example in Python",
"extras": {"author": "Jane Doe"}
}
],
"stage_timings": {"search": 0.08, "rerank": 0.12},
"channel_lists": {"passages": ["hit-789"]},
"facets": {"author": {"Jane Doe": 1}},
"node_ids": ["node-456"]
}
```
## HF CPU embedding contract
Use `embeddinggemma2-text-v1`: Ollama `embeddinggemma-2:270m`, 8192-token maximum,
768 native dimensions -> first 512 -> L2 normalization. All five primary pgvector
stores must be `vector(512)`. Never mix model identities even at equal dimensions;
index/profile mismatches must fail without dropping or reusing old vectors.
The baseline image preloads only Gemma; chat and reranking remain optional.
See `deploy/env.hf.cpu.example` and `deploy/README.ollama.md`. Before production,
commit and stage the exact source, build that staged tree, and run
`/app/entrypoint.sh --qualify` inside the local image (it runs the qualification
script with the service configuration). Do not upload a
production deployment until both the full build and real qualification pass.
## 4. Tricks and Ongoing Deployment Best Practices
### Custom Deployment Script
- Deployments to Hugging Face Spaces must use the custom `deploy/hf_space.py` complete-tree helper script rather than a plain `hf upload`. Use `python deploy/hf_space.py stage --revision HEAD --output /tmp/brainapi-hf-source` followed by `python deploy/hf_space.py upload --revision HEAD` to ensure the staged tree correctly matches the committed revision.
### Environment Variable Normalization
- String environment variables mapped into configuration classes (e.g., `provider`, `model`, `profile` in `src/config.py`) must be explicitly normalized early using `.strip()` and `.lower()` at the boundary to prevent invisible whitespace or case mismatch validation errors.
- When logging environment variable diagnostics in shell scripts like `entrypoint.sh`, place `echo` and `printf` statements after the fallback default evaluation variables are evaluated (e.g., `export VAR="${VAR:-default}"`) to ensure the effective runtime configurations are captured.
### Docker and Hub Constraints
- If a Hugging Face Space configured with the Docker SDK reports 'missing an app file', it means the `Dockerfile` is missing from the remote repository and must be explicitly uploaded alongside the `README.md` to trigger the build.
- The `deploy/` directory must not be excluded in `.dockerignore` so that Supervisord and Nginx configurations can be copied during Docker image builds.
- `.dockerignore` must exclude `node_modules/`, `console/node_modules/`, and `tui/node_modules/` to prevent copying local node dependencies into Docker build stages.
- The `README.md` requires Hugging Face YAML frontmatter at the very top of the file including `title: BrainAPI`, `emoji`, `colorFrom`, `colorTo`, `sdk: docker`, `app_port: 7860`, and `pinned` configurations to satisfy constraints.
- Do not hardcode Hugging Face access token strings in repository files like `Agent.md`, as HF Hub security filters reject commits containing raw tokens.
### Docker Startup & Service Coordination
- In Supervisord process definitions, the Celery worker application module is `src.workers.app:ingestion_app` and the MCP ASGI server module is `src.services.mcp.app:app`.
- For Hugging Face Spaces compatibility, the API is configured in `deploy/supervisord.conf` under `[program:brainapi-api]` to run Uvicorn on `0.0.0.0` port `7860` natively (or handled by an Nginx reverse proxy on 7860 to internal 8000).
- Setting `serverSelectionTimeoutMS` (e.g. 2000ms) on `PyMongoClient` prevents 30-second blocking timeouts when MongoDB is offline during startup.
- The PostgreSQL extension `vector` is pre-created in `template1` as superuser `postgres` in `entrypoint.sh` so that newly initialized workspace databases automatically inherit `pgvector` without requiring `SUPERUSER` privileges for user `brainapi`.
- In all-in-one container deployments, Supervisord orchestrates local PostgreSQL (with `pgvector`), Redis, FastAPI API, MCP server, Celery worker, and Nginx, using persistent secrets stored in `/data/brainapi/internal-secrets.env`.
- In standalone deployment container environments, setting `PIPELINE_MODE=lightweight` and `EMBEDDINGS_PROVIDER=mock` or `fastembed` avoids hard runtime dependencies on external LLM services or Ollama instances.
### Security
- `SYSTEM_PAT` must be provided as an environment variable or Hugging Face Space Secret and never hardcoded in repository files or test scripts.
- Public UI and documentation endpoints (`/`, `/console`, `/docs`, `/redoc`, `/health`, `/openapi.json`, `/api-docs`, `/favicon.ico`) must be excluded from `BrainPATMiddleware` and `BrainMiddleware` authentication checks. `GET /` redirects to `/console/`.
### Testing and Documentation Rules
- Functional API endpoints (e.g., `/retrieve/context`, `/retrieve/search`) must be explicitly documented in `Agent.md` under the `### Functional Endpoints` section, including their Method, Path, Purpose, Request, and Response structures.
- API endpoints documented in `Agent.md` should strictly match the actual implementation (route decorators and Pydantic models). The canonical HTTP method (e.g., POST) should be presented as the primary interface, without modifying API behavior just to match docs.
- The local test suite must be executed using `PYTHONPATH=tests poetry run pytest` to resolve import errors for test helper modules.
- `Config` in `src/config.py` conditionally instantiates database sub-configurations (`mongo`, `milvus`, `neo4j`, `postgresql`) based on `DATA_DB`, `VECTOR_DB`, and `GRAPH_DB` environment variables.
## 4. Tricks and Ongoing Deployment Best Practices
### Custom Deployment Script
- Deployments to Hugging Face Spaces must use the custom `deploy/hf_space.py` complete-tree helper script rather than a plain `hf upload`. Use `python deploy/hf_space.py stage --revision HEAD --output /tmp/brainapi-hf-source` followed by `python deploy/hf_space.py upload --revision HEAD` to ensure the staged tree correctly matches the committed revision.
### Environment Variable Normalization
- String environment variables mapped into configuration classes (e.g., `provider`, `model`, `profile` in `src/config.py`) must be explicitly normalized early using `.strip()` and `.lower()` at the boundary to prevent invisible whitespace or case mismatch validation errors.
- When logging environment variable diagnostics in shell scripts like `entrypoint.sh`, place `echo` and `printf` statements after the fallback default evaluation variables are evaluated (e.g., `export VAR="${VAR:-default}"`) to ensure the effective runtime configurations are captured.
### Docker and Hub Constraints
- If a Hugging Face Space configured with the Docker SDK reports 'missing an app file', it means the `Dockerfile` is missing from the remote repository and must be explicitly uploaded alongside the `README.md` to trigger the build.
- The `deploy/` directory must not be excluded in `.dockerignore` so that Supervisord and Nginx configurations can be copied during Docker image builds.
- `.dockerignore` must exclude `node_modules/`, `console/node_modules/`, and `tui/node_modules/` to prevent copying local node dependencies into Docker build stages.
- The `README.md` requires Hugging Face YAML frontmatter at the very top of the file including `title: BrainAPI`, `emoji`, `colorFrom`, `colorTo`, `sdk: docker`, `app_port: 7860`, and `pinned` configurations to satisfy constraints.
- Do not hardcode Hugging Face access token strings in repository files like `Agent.md`, as HF Hub security filters reject commits containing raw tokens.
### Docker Startup & Service Coordination
- In Supervisord process definitions, the Celery worker application module is `src.workers.app:ingestion_app` and the MCP ASGI server module is `src.services.mcp.app:app`.
- For Hugging Face Spaces compatibility, the API is configured in `deploy/supervisord.conf` under `[program:brainapi-api]` to run Uvicorn on `0.0.0.0` port `7860` natively (or handled by an Nginx reverse proxy on 7860 to internal 8000).
- Setting `serverSelectionTimeoutMS` (e.g. 2000ms) on `PyMongoClient` prevents 30-second blocking timeouts when MongoDB is offline during startup.
- The PostgreSQL extension `vector` is pre-created in `template1` as superuser `postgres` in `entrypoint.sh` so that newly initialized workspace databases automatically inherit `pgvector` without requiring `SUPERUSER` privileges for user `brainapi`.
- In all-in-one container deployments, Supervisord orchestrates local PostgreSQL (with `pgvector`), Redis, FastAPI API, MCP server, Celery worker, and Nginx, using persistent secrets stored in `/data/brainapi/internal-secrets.env`.
- In standalone deployment container environments, setting `PIPELINE_MODE=lightweight` and `EMBEDDINGS_PROVIDER=mock` or `fastembed` avoids hard runtime dependencies on external LLM services or Ollama instances.
### Security
- `SYSTEM_PAT` must be provided as an environment variable or Hugging Face Space Secret and never hardcoded in repository files or test scripts.
- Public UI and documentation endpoints (`/`, `/console`, `/docs`, `/redoc`, `/health`, `/openapi.json`, `/api-docs`, `/favicon.ico`) must be excluded from `BrainPATMiddleware` and `BrainMiddleware` authentication checks. `GET /` redirects to `/console/`.
### Testing and Documentation Rules
- Functional API endpoints (e.g., `/retrieve/context`, `/retrieve/search`) must be explicitly documented in `Agent.md` under the `### Functional Endpoints` section, including their Method, Path, Purpose, Request, and Response structures.
- API endpoints documented in `Agent.md` should strictly match the actual implementation (route decorators and Pydantic models). The canonical HTTP method (e.g., POST) should be presented as the primary interface, without modifying API behavior just to match docs.
- The local test suite must be executed using `PYTHONPATH=tests poetry run pytest` to resolve import errors for test helper modules.
- `Config` in `src/config.py` conditionally instantiates database sub-configurations (`mongo`, `milvus`, `neo4j`, `postgresql`) based on `DATA_DB`, `VECTOR_DB`, and `GRAPH_DB` environment variables.
## Credential model
`SYSTEM_PAT` is the single administrator credential across HTTP, console, and MCP.
The deprecated `BRAINPAT_TOKEN` may only alias that same value; a conflict fails
startup. Brains/workspaces do not generate credentials. Issue named access tokens
via `/system/access-tokens`, copy the plaintext once, and revoke independently.
Browser login uses `/auth/session` and `/auth/me`; a system session has no selected
brain (`brain_id=null`). The console stores no submitted access credential.
See `docs/security/credentials.md` for legacy migration and exposed-token rotation.
`/health` reports durability. Ephemeral staging requires explicit
`ALLOW_EPHEMERAL_STORAGE=true` and remains degraded / production NO-GO unless the
operator explicitly accepts the checkpointed-production policy documented below.
## GitHub Brain content recovery
Read [content checkpoint/recovery instructions](docs/content-backup.md) before
working on persistence. HF startup restores validated logical checkpoints from
`JsonLord/nodepad-brain-backup:main` using the separate `GITHUB_PAT` Space secret,
before workspace bootstrap and serving. Never back up auth registries/tokens,
Redis, internal secrets, or PGDATA; never force push or overwrite nonempty local
state of unknown lineage. API/MCP check the current container's restore gate.
Configure the documented `BRAIN_BACKUP_*` variables; keep async checkpoint RPO and
ephemeral health limitations explicit. No automatic deployment. The disposable
round-trip gate is `scripts/qualify_content_backup.py`; never point it at real
Brain databases. Auth tokens are separately reissued after ephemeral recovery.
For planned HF restarts, quiesce writers and verify a completed remote checkpoint
before replacement. HF replacement startup can overlap the old container's final
shutdown push; do not rely on that final push as a restore barrier. Compare the
restored commit with the intended checkpoint before resuming writes. See the
[live qualification and observed limitations](docs/content-backup-live-qualification.md).
The administrator maintenance API now enforces that sequence: quiesce/checkpoint,
record remotely verified SHA, rebuild, verify replacement restored/current SHA and
retrieval while still held, then explicitly resume. See `/system/backup/status`.
A manifest handoff hold survives replacement. Startup remote-head advances fail
closed before serving. Never bypass a hold or lineage failure to force readiness.
`BRAIN_BACKUP_MAX_RPO_SECONDS` defaults to the checkpoint interval (300).
`ALLOW_CHECKPOINTED_PRODUCTION=false` preserves ephemeral production NO-GO. Only
an explicit operator opt-in can accept checkpointed production, and only while
all remote/RPO/auth/database/embedding/access-log checks pass. Report the policy,
observed checkpoint age, and `zero_loss_durable=false` without implying zero loss.
|