diff --git a/docs/BRIEF_OLLAMA_OPERATORS.md b/docs/BRIEF_OLLAMA_OPERATORS.md new file mode 100644 index 0000000..18230b3 --- /dev/null +++ b/docs/BRIEF_OLLAMA_OPERATORS.md @@ -0,0 +1,25 @@ +# MODELBEAST — ollama operators brief (Opus handover) + +**From:** the asset-campaign session (2026-07-13). **Decision (John + Fable):** MODELBEAST is +THE universal queue for all local model work on the tailnet — no second queue system. Direct +Ollama calls (:11434) stay fine for quick interactive hits, but BULK LLM/vision sweeps must +ride the job queue so they don't fight Klein/TRELLIS for Metal. + +## The job: two new operators (mirror an existing operator's manifest+run.py pattern) + +1. **`ollama_vision`** [category: llm] — params: `{model: "gemma3:4b", prompt, temperature=0}`, + accepts: image (the job's asset), produces: text (a .json/.txt asset with the response). + Implementation = one POST to localhost:11434/api/generate with the asset base64'd into + `images`. Resource lane: gpu (that's the whole point — arbitration with image/mesh gen). + +2. **`ollama_llm`** [category: llm] — same but text-only (`/api/chat`), no input asset, + `{model: "qwen3:8b|qwen3:32b|qwen3:235b", prompt|messages}`. + +Notes: +- Keep operators thin — Ollama does the work; the operator is just queue admission + asset IO. +- A bulk sweep is then N jobs (one per image) — the lane serialises them gracefully and + `/api/jobs` gives progress/retry/cancel for free. No new batch machinery. +- pgvector embeddings: NOT now (deferred by design). When un-deferred it's one more thin + operator (`ollama_embed` → /api/embed); DB writes stay client-side. +- Test: submit 3 ollama_vision jobs while a flux_local job runs; assert FIFO within the gpu + lane and all 4 complete. diff --git a/server/operators/bg_remove_local/manifest.json b/server/operators/bg_remove_local/manifest.json index be7cabc..ba429e0 100644 --- a/server/operators/bg_remove_local/manifest.json +++ b/server/operators/bg_remove_local/manifest.json @@ -7,7 +7,7 @@ "produces": ["image"], "resources": "gpu", "entry": "run.py", - "python": "/Users/m3ultra/Documents/MODELBEAST/venvs/rmbg/bin/python", + "python": "venvs/rmbg/bin/python", "params_schema": { "type": "object", "properties": { diff --git a/server/operators/flux_local/manifest.json b/server/operators/flux_local/manifest.json index 071babd..1cb32c5 100644 --- a/server/operators/flux_local/manifest.json +++ b/server/operators/flux_local/manifest.json @@ -7,7 +7,7 @@ "produces": ["image"], "resources": "gpu", "entry": "run.py", - "python": "/Users/m3ultra/Documents/MODELBEAST/venvs/mflux/bin/python", + "python": "venvs/mflux/bin/python", "params_schema": { "type": "object", "properties": { diff --git a/server/operators/mflux_image_edit/manifest.json b/server/operators/mflux_image_edit/manifest.json index 8d0d8ce..918ebde 100644 --- a/server/operators/mflux_image_edit/manifest.json +++ b/server/operators/mflux_image_edit/manifest.json @@ -7,7 +7,7 @@ "produces": ["image"], "resources": "gpu", "entry": "run.py", - "python": "/Users/m3ultra/Documents/MODELBEAST/venvs/mflux/bin/python", + "python": "venvs/mflux/bin/python", "params_schema": { "type": "object", "properties": { diff --git a/server/operators/seedvr2_upscale/manifest.json b/server/operators/seedvr2_upscale/manifest.json index d3e7e8e..cd69a74 100644 --- a/server/operators/seedvr2_upscale/manifest.json +++ b/server/operators/seedvr2_upscale/manifest.json @@ -7,7 +7,7 @@ "produces": ["image"], "resources": "gpu", "entry": "run.py", - "python": "/Users/m3ultra/Documents/MODELBEAST/venvs/mflux/bin/python", + "python": "venvs/mflux/bin/python", "params_schema": { "type": "object", "properties": { diff --git a/server/operators/sf3d/manifest.json b/server/operators/sf3d/manifest.json index f0c12a0..0032be1 100644 --- a/server/operators/sf3d/manifest.json +++ b/server/operators/sf3d/manifest.json @@ -7,7 +7,7 @@ "produces": ["model"], "resources": "gpu", "entry": "run.py", - "python": "/Users/m3ultra/Documents/MODELBEAST/venvs/sf3d/bin/python", + "python": "venvs/sf3d/bin/python", "params_schema": { "type": "object", "properties": { diff --git a/server/operators/trellis_mac/manifest.json b/server/operators/trellis_mac/manifest.json index d5a039d..e97356a 100644 --- a/server/operators/trellis_mac/manifest.json +++ b/server/operators/trellis_mac/manifest.json @@ -7,7 +7,7 @@ "produces": ["model"], "resources": "gpu", "entry": "run.py", - "python": "/Users/m3ultra/Documents/MODELBEAST/vendor/trellis-mac/.venv/bin/python", + "python": "vendor/trellis-mac/.venv/bin/python", "params_schema": { "type": "object", "properties": { diff --git a/server/runner.py b/server/runner.py index c2270b8..82ef728 100644 --- a/server/runner.py +++ b/server/runner.py @@ -193,8 +193,13 @@ class Runner: outdir = Path(job["outdir"]) entry = Path(op["dir"]) / op.get("entry", "run.py") - python = op.get("python") or sys.executable - if op.get("python") and not Path(python).exists(): + # a manifest "python" may be relative to the repo root (portable across + # machines) or absolute (legacy); resolve relative ones against db.ROOT + op_py = op.get("python") + if op_py and not Path(op_py).is_absolute(): + op_py = str(db.ROOT / op_py) + python = op_py or sys.executable + if op_py and not Path(python).exists(): await self._update(con, job_id, status="error", finished_at=db.now(), error=f"operator not installed — {python} missing. " f"Run its install script under scripts/.")