84 lines
4.9 KiB
Markdown
84 lines
4.9 KiB
Markdown
# MiroFish deploy (agent.profikid.nl)
|
|
|
|
Single-host Docker deployment of the [MiroFish swarm-intelligence engine](https://github.com/666ghj/MiroFish) reforked to use **Graphiti + FalkorDB** instead of Zep Cloud.
|
|
|
|
## What you get
|
|
|
|
| URL | Service |
|
|
| --- | --- |
|
|
| `https://mirofish.agent.profikid.nl` | MiroFish web UI + API (frontend on :3000, Flask API on :5001, both inside the mirofish container) |
|
|
| `mirofish_net` (internal Docker network) | FalkorDB (in-memory graph store, port 6379) |
|
|
|
|
Traefik (running on the host as the `traefik` Docker network) auto-issues a Let's Encrypt cert for `mirofish.agent.profikid.nl`.
|
|
|
|
## Files
|
|
|
|
```
|
|
/docker/mirofish/ <-- everything below lives here
|
|
├── docker-compose.yml <-- mirofish + falkordb + e2e (opt-in)
|
|
├── secrets.env <-- LLM_API_KEY, FALKORDB creds
|
|
├── bootstrap.sh <-- one-time host checks
|
|
├── up.sh <-- build + bring up mirofish + falkordb
|
|
├── e2e.sh <-- run the in-container end-to-end test
|
|
├── health.sh <-- /health, container status, falkordb ping
|
|
├── Dockerfile.e2e <-- e2e test image (inherits mirofish:latest)
|
|
└── e2e_test.py <-- the test itself
|
|
```
|
|
|
|
## Deploy
|
|
|
|
```bash
|
|
ssh root@agent.profikid.nl
|
|
mkdir -p /docker/mirofish
|
|
cd /docker/mirofish
|
|
# Drop the contents of this directory here (or git clone the repo and copy deploy/ -> .)
|
|
./bootstrap.sh # verifies docker / dns / file presence
|
|
./up.sh # builds the image, brings up mirofish + falkordb
|
|
```
|
|
|
|
After ~90s (FalkorDB cold start + embedding model download on first build only), the URL `https://mirofish.agent.profikid.nl` should respond.
|
|
|
|
## E2E test
|
|
|
|
```bash
|
|
cd /docker/mirofish
|
|
./e2e.sh
|
|
```
|
|
|
|
This builds `mirofish-e2e:latest` (a thin layer on top of `mirofish:latest` that runs `e2e_test.py` as the entrypoint), then runs it as a one-shot container against the real `falkordb` sidecar. It:
|
|
|
|
1. Verifies FalkorDB is reachable (raw TCP probe)
|
|
2. Runs the real `GraphBuilderService` against the Iran/US/Israel OSINT briefing seed text
|
|
3. Reads back from FalkorDB via the adapter (`get_all_nodes`, `get_all_edges`)
|
|
4. Re-verifies with a raw `falkordb.FalkorDB` client (independent check)
|
|
5. Prints PASS / FAIL with node + edge counts
|
|
|
|
Expected on first run: **~8 entities, ~8 edges** in FalkorDB after the 2-chunk run (`E2E_MAX_CHUNKS=2`). Wall time ~3-4min on the first call (LLM is doing the extraction; reasoning tokens make M3 slow). Tune `E2E_MAX_CHUNKS` higher in `docker-compose.yml` to test with more seed text.
|
|
|
|
## How the refactor differs from upstream
|
|
|
|
Upstream MiroFish uses [Zep Cloud](https://www.getzep.com/) for the knowledge graph. This fork replaces it with [Graphiti](https://github.com/getzep/graphiti) (the open-source engine behind Zep) backed by [FalkorDB](https://www.falkordb.com/) (a Redis-protocol graph store). All graph operations go through a Zep-shaped facade in `backend/app/services/graphiti_service.py` so the rest of the MiroFish code (which still speaks Zep) didn't have to change.
|
|
|
|
Key wiring:
|
|
|
|
- `MinimaxLLMClient` — Graphiti's LLMClient ABC implemented against MiniMax M3 (`https://api.minimax.io/v1`). Uses the `tools` API for structured output because M3 ignores `response_format: json_object`.
|
|
- `M3RerankerClient` — chat-completion True/False reranker (M3 returns `logprobs: None`, so the stock OpenAI reranker that reads logprobs breaks).
|
|
- `HashEmbedder` — deterministic 384-dim embedder so the test image doesn't need to download the full `sentence-transformers` multilingual model. The production image still uses the real model (set `EMBEDDING_MODEL=sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2` in `secrets.env` to switch).
|
|
- `FalkorDriver` (from `graphiti-core[falkordb]>=0.20.0`) — the actual graph store. No Neo4j, no Bolt, just a Redis-protocol TCP socket to the sidecar.
|
|
|
|
## How to upgrade
|
|
|
|
```bash
|
|
cd /docker/mirofish
|
|
git pull # in the parent MiroFish repo
|
|
./up.sh --rebuild # rebuild + restart
|
|
./e2e.sh # smoke-test
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
- **FalkorDB healthcheck fails** — check `docker compose logs falkordb`. The `falkordb/falkordb:latest` image is small; first-pull can take a minute.
|
|
- **`/health` returns 200 but `/api/ontology/generate` times out** — the embedding model is downloading on first request. Wait, or run with a prebuilt `mirofish:latest` that has the model baked in (the `Dockerfile` already does this in step 4).
|
|
- **M3 returns 0 entities** — the M3 endpoint is shared; rate limiting or reasoning-token quirks can cause this. Check `docker compose logs mirofish | grep graphiti_service` and the raw LLM payloads.
|
|
- **Cert issuance stuck in Traefik** — confirm `TRAEFIK_HOST=agent.profikid.nl` and that the `traefik` Docker network exists. Traefik must be on the same network as the `mirofish` container.
|