mesh-llm / mesh
AGENTS.md3.8k starsChanged 20 days agoApache-2.0View on GitHub
These instructions apply under mesh/ in addition to the root AGENTS.md. Paths and just commands below are relative to the workspace root. Mesh depends on Skippy; do not move Skippy-native behavior into Mesh crates. The maintained website source lives in mesh/website/. Eleventy writes generated static-hosting output into root docs/; authored documentation lives under mesh/docs/ and skippy/docs/. Do not hand-edit generated website files. The build runs Tailwind, Eleventy and Pagefind. It copies website source assets and root install.sh, install.ps1 and install.md…
- Deletes or force-pushes
We split this AGENTS.md into the rules it gives an agent
38 rules. About 0 are common, 16 are distinctive, and 22 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈16
Distinctive · estimate
This author's own choices. Worth a look.
22
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 50
If just build fails on the UI step with npm error Exit handler never called!, run just ui-clean and then just build.
- Very specific: line 114
Keep mesh/crates/mesh-llm-host-runtime/src/lib.rs slim — it is a small entry point, not a junk drawer.
- Very specific: line 117
Use semantic ownership for module placement.
- Distinctive: line 191
Keep real-QUIC regression tests proving local execution, local-unavailable rejection without a second hop, and continued local-user HTTP …
- Distinctive: line 199
When adding new gossip fields, stream types, or changing wire format, explicitly consider what happens when an older node receives the new …
- Distinctive: line 201
If a change would break mixed-version meshes, explicitly flag it as a breaking protocol change and ask the developer before proceeding.
- Distinctive: line 202
Test compatibility by running the current branch against a released binary on a second node.
- Distinctive: line 206
When iterating on the plugin protocol, always consider protocol compatibility.
- Distinctive: line 208
If a protocol change may be breaking, explicitly ask the developer whether the change is intended to be breaking.
- Distinctive: line 209
If the change is not intended to be breaking, the previous version of the plugin protocol must continue to be supported.
- Distinctive: line 210
Do not silently ship plugin protocol changes that strand older plugins or hosts without confirming that outcome is acceptable.
- Very specific: line 226
Do not point the TUI backend, or the enter/exit escape writers, at io::stderr().
- Distinctive: line 234
Do not perform that clear on every draw.
- Very specific: line 237
Prefer OutputEvent or tracing in runtime code regardless — captured lines have no level and are shown with a stdout context.
- Very specific: line 245
Read mesh/docs/design/TESTING.md before running tests.
- Distinctive: line 254
When making changes that touch gossip, routing, proxy, election, or capability advertisement, test against at least two nodes before …
- Distinctive: line 270
Default the launch to a normal foreground run (TUI visible) unless you have a specific reason to suppress UI surfaces.
- Very specific: line 288
Do not reach for --headless to "go quiet" — that is a recurring mistake.
- Very specific: line 294
If a change is reachable from the shipped binary, run at least cargo check -p mesh-llm and cargo clippy -p mesh-llm --all-targets -- -D …
- Very specific: line 299
Use the repo's supported workflow and run just build.
- Very specific: line 300
If just build fails on the UI step with npm error Exit handler never called!, run just ui-clean and then rerun just build.
- Distinctive: line 326
If an instance is wedged badly enough that the scoped stop path cannot reach it, fall back to an emergency kill:
- Very specific: line 334
When running mesh-llm serve from an agent for testing, the process is non-interactive — it just runs.
- Very specific: line 342
Wait for models to appear via polling curl -s http://localhost:9337/v1/models before sending requests.
- Very specific: line 353
Verify clean — ps -eo pid,args | grep -E 'mesh-llm' | grep -v grep must be empty.
- Very specific: line 358
Verify version — mesh-llm --version on every node.
- Very specific: line 361
Verify exactly 1 mesh-llm process per node.
- Distinctive: line 362
Verify no external llama serving child processes are required.
- Very specific: line 364
Check /api/status peers for new version string.
- Distinctive: line 365
Verify expected peer count.
- Very specific: line 369
Test inference through every model in /v1/models.
- Very specific: line 370
Test /v1/ passthrough on port 3131.
- Very specific: line 374
If the embedded runtime fails to load, check mesh-llm stderr/log output and ~/.mesh-llm/runtime/ for the active instance metadata.
- Very specific: line 416
If <archive>.sha256 exists, verify it and fail the install on malformed checksum data or checksum mismatch.
- Distinctive: line 418
If the sidecar is missing for a legacy/current release, warn and continue by default.
- Very specific: line 420
If MESH_LLM_REQUIRE_CHECKSUM=1 is set, a missing sidecar is fatal.
- Distinctive: line 422
Do not change installer behavior to hard-require sidecars by default unless the release policy also guarantees every supported/pinned …
- Very specific: line 429
No domain logic in mesh/crates/mesh-llm/src/.
≈ “Common” is an estimate: at least 1 in 5 of the 36,368 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
MeshLLM Agent Notes
These instructions apply under mesh/ in addition to the root AGENTS.md. Paths and just commands below are relative to the workspace root. Mesh depends on Skippy; do not move Skippy-native behavior into Mesh crates.
Key docs
| Doc | What it covers |
mesh/docs/README.md | Documentation map |
mesh/docs/MESHES.md | Public/private meshes, discovery, and join flows |
mesh/docs/design/DESIGN.md | Architecture, protocols, and features |
mesh/docs/design/TESTING.md | Test playbook and remote deploy |
mesh/docs/design/MULTI_MODAL.md | Multimodal architecture |
mesh/docs/design/VIRTUAL_LLM.md | Virtual LLM collaboration |
mesh/docs/plugins/README.md | Plugin architecture |
mesh/docs/EXO_COMPARISON.md | MeshLLM versus Exo |
mesh/deploy/fly/README.md | Fly.io deployment |
mesh/crates/mesh-llm/README.md | Rust crate overview and file map |
mesh/crates/mesh-llm/TODO.md | Current work and backlog |
mesh/crates/mesh-llm-analytics/README.md | The only vendor-reporting crate; read before adding events |
mesh/website/src/docs/pages/analytics.md | Public analytics disclosure |
tools/relay-fly-legacy/README.md | Archived relay reference; production uses services.iroh.computer |
Public Website
The maintained website source lives in mesh/website/. Eleventy writes generated static-hosting output into root docs/; authored documentation lives under mesh/docs/ and skippy/docs/. Do not hand-edit generated website files.
just website-build # build website and crate API docs into root docs/
just website-dev # Eleventy dev server on port 8765
just website-clean # remove generated output
just crate-docs # regenerate published crate API docsThe build runs Tailwind, Eleventy and Pagefind. It copies website source assets and root install.sh, install.ps1 and install.md into the generated tree. mesh/website/src/assets/site.generated.css is generated by Tailwind.
Building and packaging
just meshbuilds only the backend-neutral MeshLLM host and console. It consumes Skippy's separately packaged runtime and does not compile a backend into the host.- Bare
justbuilds Skippy first, then MeshLLM.just release-builddoes the same for release products.just release-host-buildbuilds only the release host. just bundlecreates a portable product tarball.just release-bundle vX.Y.Z <output>packages the release host and one selected runtime undernative-runtimes/.just ui-devstarts Vite;just ui-cleanclears stale UI installs;just stop,just test, andjust autooperate on the local MeshLLM runtime.
A release binary left in target/release/mesh-llm may predate the latest debug build. Its presence does not prove it contains current code; rerun just release-build when in doubt. For serious testing and deployment, use a composed release product.
The host dependency policy is enforced by cargo xtool native verify-host-dependencies. Release, installer, SDK, native-package, and image lanes must not bypass it or copy backend libraries beside the host. For isolated runtime discovery, set MESH_LLM_NATIVE_RUNTIME_BUNDLE_DIR="$PWD/dist/native-runtimes" and a fresh MESH_LLM_NATIVE_RUNTIME_CACHE_DIR. Discovery never searches the working directory. Do not reintroduce an external llama-server or rpc-server lane.
npm "Exit handler never called" error
If just build fails on the UI step with npm error Exit handler never called!, run just ui-clean and then just build. This can follow branch switches that leave node_modules inconsistent with the lockfile.
Workspace Crates
Product crates live under mesh/crates/. The most important crates:
Shipped binary and CLI surface:
mesh-llm/— shipped binary;main.rsbuilds the Tokio runtime,lib.rsownsrun_main(CLI parse → one-shot command dispatch via itscommands/module → runtime handoff). No domain logic here.mesh-llm-cli/— Clap types, argument parsing, serve/client surface normalization. No handlers.mesh-llm-commands/— user-facing command handlers (auth, gpus, update, skills, agent launchers like goose/pi/opencode/claude, plugin, benchmark, model packaging).mesh-llm-tui/— terminal UI and progress output surface.mesh-llm-events/— shared runtime event and output contracts (OutputEvent, log formats).
Host and client runtimes:
mesh-llm-host-runtime/— the host-side monolith. Owns runtime orchestration, mesh, inference, networking, management API, plugins, models, system integration. This is where most changes land.mesh-client/(mesh-llm-client) — lighter parallel client surface with its owninference/,network/,models/,mesh/modules. Used as a dev/test surface and for client-only deployments.mesh-llm-node/,mesh-llm-embedded-runtime/— embeddable node primitives and in-process full-node embedding API.mesh-llm-config/— configuration parsing and validation (~/.mesh-llm/config.toml).mesh-llm-ui/— React web console and embedded asset crate (shadcn/ui patterns, see https://ui.shadcn.com/llms.txt).mesh-llm-console-server/— static file server for embedded console assets.
Shared foundations:
mesh-llm-types/— shared model/capability types used across crates.mesh-llm-protocol/— wire protocol types and protobuf bindings.mesh-llm-routing/— routing primitives shared across host and client.mesh-llm-system/— machine-local hardware, benchmark, autoupdate, process helpers.mesh-llm-identity/— owner identity and envelope crypto primitives.mesh-llm-plugin/— plugin runtime/DSL primitives.mesh-llm-plugin-manager/— plugin package management (catalog, install, store).mesh-llm-skills/— agent skill data model and installer primitives.
SDK and API surface:
mesh-llm-sdk/— Rust SDK facade for clients and embedded serving.mesh-llm-api-server/,mesh-llm-api-client/— public Rust SDK APIs for embedding nodes / client-only use.mesh-llm-ffi/,mesh-llm-nodejs/— FFI bindings and Node.js native addon.mesh-mixture-of-agents/— Mixture-of-Agents fan-out/arbitration engine.
Tools and benchmarks:
mesh-llm-test-harness/— integration test harness binary.
This list covers the crates you are most likely to touch; check mesh/crates/ and each crate's Cargo.toml description for anything not listed.
Other product directories:
mesh/website/— Eleventy source for the public website; builds into rootdocs/.mesh/docs/design/— Mesh architecture, protocols, and testing docs.mesh/docs/plugins/— Plugin architecture docs and plans.mesh/docs/specs/— Focused Mesh behavior specs.mesh/sdk/— SDK packaging for Node, Swift, Kotlin.mesh/deploy/fly/— Fly.io deployment (console + API client apps).mesh/evals/— Mesh benchmarking and evaluation scripts.tools/relay-fly-legacy/— Archived self-hosted iroh relay reference; production uses services.iroh.computer.
Module Structure Rules
These rules apply primarily inside mesh/crates/mesh-llm-host-runtime/src/ (the main host monolith), and by analogy inside mesh/crates/mesh-client/src/. New peer crates should still follow the semantic-ownership principles below.
The host-runtime crate root should stay minimal.
- Keep
mesh/crates/mesh-llm-host-runtime/src/lib.rsslim — it is a small entry point, not a junk drawer. - New code should go into an existing domain directory when possible.
Use semantic ownership for module placement. Inside mesh/crates/mesh-llm-host-runtime/src/:
runtime/— top-level process orchestration, startup/runtime coordination, runtime instance, capacity, split planning, proxy lifecycle.network/— request routing, proxying, tunneling, relay/discovery networking, request-affinity logic, endpoint rewrite, target health, OpenAI transport glue.inference/— model-serving logic, election, launch, pipeline, MoE behavior, embedded skippy integration.system/— machine-local environment and platform concerns (hardware detection, benchmarking, self-update, local system integration).models/— model catalog, resolution, downloads, local model storage, model metadata.mesh/— peer membership, gossip, heartbeats, identity, peer state, mesh node behavior.plugin/— plugin host, plugin runtime, transport, config, MCP bridge support.plugins/— concrete in-tree plugins (currentlyblobstore/; most plugins like blackboard, openai-endpoint, and flash-moe/ln are external packages installed viamesh-llm plugins install).api/— management API surface and route handling.protocol/— wire protocol types, encoding/decoding, conversions.runtime_data/— runtime data collection, API views, status snapshots.crypto/— host-side crypto helpers.
CLI ownership rule.
- Clap types, argument parsing, and surface normalization belong in
mesh/crates/mesh-llm-cli/. - User-facing command handlers belong in
mesh/crates/mesh-llm-commands/(or the shipped binary'smesh/crates/mesh-llm/src/commands/dispatch layer for wiring). - Domain modules in
mesh-llm-host-runtimeshould not own Clap parsing or top-level command dispatch. - Domain modules may expose reusable functions that command handlers call.
Current structure notes.
- Request-affinity code belongs with networking/routing behavior (
network/affinity.rs), notsystem/. - Plugin MCP support belongs inside
mesh-llm-host-runtime/src/plugin/, not as a separate root module. - Model command handlers belong in
mesh-llm-commands/(ormesh/crates/mesh-llm/src/commands/for dispatch wiring); host-runtimemodels/should stay domain-focused. - The shipped binary crate (
mesh/crates/mesh-llm/) carries CLI dispatch wiring only; do not move domain logic into it.
Key Source Files
Host runtime (main monolith — mesh/crates/mesh-llm-host-runtime/src/):
lib.rs— crate entry; exposes the runtime entrypoints (run_runtime_initialized,initialize_host_runtime) called frommesh/crates/mesh-llm/src/lib.rs.runtime/mod.rs— top-level startup flows, runtime orchestration, command dispatch.runtime/instance.rs— per-instance runtime directory management:InstanceRuntime, pidfiles, flock liveness, scoped orphan reaping, local instance scanning.runtime/local.rs— local model startup loop.runtime/discovery.rs— discovery loops and auto-mode coordination.runtime/proxy.rs,runtime/proxy/— HTTP proxy lifecycle from the runtime side.runtime/capacity.rs,runtime/split_planning.rs,runtime/context_planning.rs— placement/sizing decisions.mesh/mod.rs—Nodestruct, mesh_id, peer management.mesh/gossip.rs— gossip wire format and peer state updates.mesh/heartbeat.rs— heartbeat publishing and freshness.inference/election.rs— host election, tensor split calculation.inference/skippy/— embedded staged runtime integration.inference/pipeline.rs— inference pipeline coordination.inference/virtual_llm.rs— virtual LLM (inter-model collaboration).network/proxy.rs— HTTP proxy: request parsing, model routing, response helpers.network/router.rs— request classification, model scoring, multimodal routing.network/nostr.rs— Nostr discovery,score_mesh(),smart_auto().network/tunnel.rs— TCP ↔ QUIC relay (RPC + HTTP).network/affinity.rs— request-affinity tracking.network/target_health.rs— target health tracking.network/openai/— OpenAI transport glue.api/mod.rs,api/routes/— management API (:3131):/api/status,/api/events,/api/discover.models/catalog.rs— model catalog, HuggingFace downloads.models/capabilities.rs— multimodal/vision/audio/reasoning capability inference.models/resolve/— model reference resolution.plugins/blobstore/mod.rs— request-scoped media object storage for multimodal.plugin/— plugin host, runtime, transport, config, MCP bridge (external plugins install viamesh-llm plugins install).
Shipped binary and CLI (mesh/crates/mesh-llm/src/, mesh/crates/mesh-llm-cli/src/, mesh/crates/mesh-llm-commands/src/):
mesh-llm/src/main.rs— builds the Tokio runtime (custom stack size viaMESH_TOKIO_STACK_SIZE) and callsmesh_llm::run_main().mesh-llm/src/lib.rs—run_main: CLI parse, one-shot command dispatch, runtime handoff.mesh-llm/src/commands/— dispatch wiring from parsedCommandvalues to handlers.mesh-llm-cli/src/parser.rs— Clap surface, serve/client arg normalization, advanced help.mesh-llm-commands/src/— user-facing handlers (auth, gpus, update, skills, agent launchers, plugin, benchmark).
Peer Inference Execution Boundary
- Local-user HTTP ingress may select a mesh host and retry eligible peers.
- Incoming QUIC HTTP inference is already assigned to this host: execute the named local model (including a registered serving plugin) or return an error to the caller. Never forward it to another mesh peer, including on local failure, missing model, automatic/virtual model selection, or routing headers.
- Incoming QUIC inference must never reconnect to the main Mesh HTTP API port (9337 by default, including configured replacements). Use in-process execution ingress; if it is unavailable, return an error. Do not restore a TCP fallback. Headers are not proof of local origin. Model-name aliases and multiple hosts advertising the same model are normal and must not weaken the boundary.
- Keep real-QUIC regression tests proving local execution, local-unavailable rejection without a second hop, and continued local-user HTTP routing when changing ingress or target selection.
Mesh Protocol Compatibility
Mesh compatibility across versions is critical. Nodes in the wild run different versions and must interoperate.
- The mesh supports mixed-version operation: QUIC ALPN
mesh-llm/1(protobuf) andmesh-llm/0(legacy JSON) nodes coexist. Do not break this. - Gossip fields, stream types, and protobuf schemas must be additive. New fields should be optional and ignored by older nodes. Do not repurpose or remove existing fields.
- When adding new gossip fields, stream types, or changing wire format, explicitly consider what happens when an older node receives the new data and when a newer node talks to an older peer.
- Capability advertisement (vision, audio, multimodal, reasoning, tool_use, moe) is gossiped to all peers and consumed by routing, the API, and the UI. Changes to capability semantics affect the whole mesh, not just the local node.
- If a change would break mixed-version meshes, explicitly flag it as a breaking protocol change and ask the developer before proceeding.
- Test compatibility by running the current branch against a released binary on a second node. Verify gossip, routing, and inference work across the version boundary.
Plugin Protocol Compatibility
When iterating on the plugin protocol, always consider protocol compatibility.
- If a protocol change may be breaking, explicitly ask the developer whether the change is intended to be breaking.
- If the change is not intended to be breaking, the previous version of the plugin protocol must continue to be supported.
- Do not silently ship plugin protocol changes that strand older plugins or hosts without confirming that outcome is acceptable.
UI Notes
For changes in mesh/crates/mesh-llm-ui/, use components and compose interfaces consistently with shadcn/ui patterns. Prefer extending existing primitives in src/components/ui/ over ad-hoc markup.
Terminal dashboard integrity
The dashboard renders to the controlling terminal (/dev/tty, CONOUT$),
never to fd 1 or fd 2, and while it owns the screen those two descriptors are
redirected into it (mesh/crates/mesh-llm-tui/src/output/console_capture.rs). Stray
println!/eprintln!, inherited child stderr, and native llama.cpp output
therefore arrive as dashboard events instead of painting over the frame.
Consequences worth knowing before changing this area:
- Do not point the TUI backend, or the enter/exit escape writers, at
io::stderr(). Capture would then redirect the dashboard into its own pipe. - Anything restoring the terminal (panic hooks, emergency writers) must release the capture before writing, or the message goes into the pipe.
- Capture cannot intercept a write to the tty by a process that did not inherit
our descriptors.
Ris the repair for that case: a physical clear plus a ratatui diff invalidation. A logicalClearwidget does not fix backend desynchronization. - Do not perform that clear on every draw. It repaints from blank and reads as a black blink; measured on an idle dashboard it was ~2.6 full repaints/s.
Prefer OutputEvent or tracing in runtime code regardless — captured lines
have no level and are shown with a stdout context. When adding a tracing
target that must reach the dashboard, add a directive for it in
runtime_tracing_subscriber: EnvFilter::from_default_env() defaults to ERROR,
so an unlisted target's warn! is dropped before the writer sees it.
Testing
Read mesh/docs/design/TESTING.md before running tests. It has all test scenarios, remote deploy instructions, and cleanup commands.
Testing matters more than usual in this project because:
- Nodes run on different machines with different hardware and OS versions. Bugs that don't reproduce locally can appear in real deployments.
- The mesh protocol is a distributed system — gossip, election, and routing interact across nodes. Single-node unit tests don't catch protocol-level regressions.
- The public mesh at meshllm.cloud runs continuously. Breaking changes that pass local tests can take down live inference for real users.
- Multimodal, MoE splitting, and multi-model routing all have complex interaction paths that are hard to reason about statically.
When making changes that touch gossip, routing, proxy, election, or capability advertisement, test against at least two nodes before merging. The deploy checklist below is not optional.
Confidence Testing (multi-node, when warranted)
For changes that affect routing, MoA, gossip, the OpenAI surface, agent harnesses, or anything multi-node, validate with these three shapes before declaring a branch ready:
- 2-node private mesh — start one node with
mesh-llm serve --model <big> --port 9337 --console 3131, grab its invite token from the JSON log, and start the second node withmesh-llm serve --gguf <small.gguf> --port 9447 --console 3145 --join <token>. Confirm peers=1 on both consoles and/v1/modelsreturns the union. Exercises QUIC tunnelling and cross-node routing. - Public mesh as a client —
mesh-llm client --autofrom a workstation. Confirmdiscovery_joinedplus a structured client-ready event (passive_mode,status=ready,role=client) in the log and an inference call against a mesh-advertised model returns. Exercises the read-only routing path agent users hit. - Agent harness — run at least one existing client smoke (
scripts/ci-goose-smoke.sh,scripts/ci-opencode-smoke.sh, orscripts/ci-pi-smoke.sh) against the local proxy with bothmodel=autoandmodel=meshto catch tool-call and reducer regressions that simple curl checks miss. Seemesh/docs/AGENTS.mdfor client setup and the direct tool-call reliability probe.
Mesh package validation
For changes to mesh-llm-host-runtime or the shipped mesh-llm binary, use -p mesh-llm for build/check (it pulls in the host runtime) and -p mesh-llm-host-runtime for focused tests.
Running mesh-llm locally
Default the launch to a normal foreground run (TUI visible) unless you have a specific reason to suppress UI surfaces. Most observation/debug tasks do not need the TUI suppressed.
mesh-llm client --auto— normal foreground run with the TUI. Use this by default.--log-format json— emits machine-parseable JSON log lines. Use this when you want to programmatically read events.--headless— disables the embedded web UI, not the TUI. The TUI still draws. Only use--headlesswhen you are intentionally avoiding the management web console — it is not the way to get a quiet background run.--no-console— fully disables the management console (HTTP API on the console port).nohup … &with a foreground binary that draws a TUI will appear to run but often exits or behaves oddly when the TUI cannot attach to a terminal. Prefer letting the developer launch the binary in their own terminal and observing via/api/status,--log-format json, or by reading stderr.
Do not reach for --headless to "go quiet" — that is a recurring mistake. If
you want quiet output, use --log-format json and parse what you need.
Rust validation
- After Rust changes, run
just no-console-print. There is no allowlist. It forbidsprintln!/eprintln!/print!/eprint!and directio::stdout()/io::stderr()handles in product code. Route operational output throughmesh_llm_events::emit_eventortracing, human-facing CLI prose throughmesh_llm_events::console_out/console_err, and a--jsonpayload throughmesh_llm_events::machine_out. Only the console output facility may hold a terminal handle; its roster isCONSOLE_OUTPUT_OWNERSintools/xtask/src/no_console_print/scope.rs. - If a change is reachable from the shipped binary, run at least
cargo check -p mesh-llmandcargo clippy -p mesh-llm --all-targets -- -D warnings. - Changes to
proto/, any Meshprotocol/module,mesh-llm-host-runtime/src/mesh/gossip.rs,mesh-llm-host-runtime/src/mesh/mod.rs, routing, election, or API serialization needcargo test -p mesh-llm-host-runtime --lib; do not stop at build-only validation.
UI validation
- Use the repo's supported workflow and run
just build. - If
just buildfails on the UI step withnpm error Exit handler never called!, runjust ui-cleanand then rerunjust build.
Deployment and cleanup
Deploy to Remote
just bundle # /tmp/mesh-llm-bundle.tar.gz — single mesh-llm binary
# scp bundle to remote, tar xzf, then on macOS: codesign -s - mesh-llm && xattr -cr <dir>For the full per-platform deploy flows, see the repo skills
.agents/skills/deploy-macos/, .agents/skills/deploy-linux-gpu/, and
.agents/skills/deploy-windows/.
Cleanup
Clean shutdown removes the instance's runtime directory automatically. Prefer the scoped runtime-aware commands first:
mesh-llm stop
just stopThose paths use the runtime metadata under ~/.mesh-llm/runtime/ to stop the tracked mesh-llm instance and its child servers cleanly.
If an instance is wedged badly enough that the scoped stop path cannot reach it, fall back to an emergency kill:
pkill -f mesh-llmRunning mesh-llm in the Background (for Testing)
When running mesh-llm serve from an agent for testing, the process is non-interactive — it just runs. There is no interactive prompt or TUI to worry about. Use standard backgrounding:
bash -c './target/debug/mesh-llm serve --model "..." --auto > /tmp/mesh.log 2>&1 & disown; echo "PID=$!"'- Do not use
--headless— it disables the web UI but does not change process behavior. The name is misleading and does not help with backgrounding. - The mesh process writes TUI-formatted output to stderr which looks like errors but is normal.
- Wait for models to appear via polling
curl -s http://localhost:9337/v1/modelsbefore sending requests. - Kill with
pkill -f "target/debug/mesh-llm"orpkill -f mesh-llm.
Deploy Checklist — MANDATORY
Every deploy to test machines MUST follow this checklist.
Before starting nodes
- Bump VERSION in the root
Cargo.toml([workspace.package] version; crates inherit it viaversion.workspace = true) so you can verify the running binary is new code. just build && just bundle- Kill ALL processes on ALL nodes —
pkill -9 -f mesh-llm - Verify clean —
ps -eo pid,args | grep -E 'mesh-llm' | grep -v grepmust be empty. - Deploy bundle — scp + tar + codesign on remote nodes.
- On every macOS node, complete the
deploy-macosskill's Local Network privacy preflight for the exact signed identity and launch context. Clear any blocking desktop alert before remote diagnosis. - Verify version —
mesh-llm --versionon every node.
After starting nodes
- Verify exactly 1 mesh-llm process per node.
- Verify no external llama serving child processes are required.
curl -s http://localhost:3131/api/statusreturns valid JSON on every node.- Check
/api/statuspeers for new version string. - Verify expected peer count.
- For same-LAN tests, require a direct iroh path to the intended LAN address from both nodes before attributing failures to candidate selection or collecting performance data.
- Test inference through every model in
/v1/models. - Test
/v1/passthrough on port 3131.
Debugging Embedded Runtime Startup
If the embedded runtime fails to load, check mesh-llm stderr/log output and
~/.mesh-llm/runtime/ for the active instance metadata. Embedded
skippy/llama.cpp native logs are redirected away from the TUI into the active
instance runtime directory:
<runtime-root>/<pid>/logs/skippy-native.logTo override the runtime root (e.g., for tests or systemd):
MESH_LLM_RUNTIME_ROOT=/path/to/custom/root— highest priorityXDG_RUNTIME_DIR— if set (typical on systemd:/run/user/{uid}/mesh-llm/runtime)$HOME/.mesh-llm/runtime— default fallback
For stale instances (crashed mesh-llm leaving behind a runtime dir):
- Other running mesh-llm instances GC dead-owner dirs older than 1 hour on startup
- Manual cleanup:
rm -rf ~/.mesh-llm/runtime/<stale_pid>/
Common failures
- nohup over SSH doesn't stick — use
bash -c "nohup ... & disown", verify process survives disconnect. - Duplicate processes — always kill-verify-start.
- codesign changes the hash — don't compare local vs codesigned remote.
Releasing
See RELEASE.md for the full process.
Current release flow: kick off the Release workflow (.github/workflows/release.yml) from the GitHub Actions UI via workflow_dispatch with the version input (e.g. v0.X.Y), or run just release v0.X.Y to preflight and dispatch that same workflow.
The dispatched workflow handles everything: it bumps versions via scripts/release-version.sh, commits the tracked version surface to main before building, generates and patches the SwiftPM manifest, packages SDK console assets, creates and pushes the release tag at a release-prep commit, builds the full artifact matrix (macOS, Linux CPU/ARM64/CUDA/CUDA-Blackwell/ROCm/Vulkan, Windows CPU/CUDA/ROCm/Vulkan), and publishes the GitHub release with generated notes. Dispatch inputs include skip_gpu_bundles and canary (dry-run: build + smoke without mutating main or publishing).
Pushing a v* tag manually also triggers the workflow, but the tag must point to main history with the matching scripts/release-version.sh update already committed; it also requires preparing Package.swift and SDK console assets in the tag commit yourself. The workflow rejects a drifted tag. See RELEASE.md and prefer the dispatch path.
Installer checksum sidecars
Release/package scripts should keep generating .sha256 sidecars for new
release archives. Do not rely on backfilling old release assets, because pinned
versions and alternate repos may not have sidecars.
install.sh and install.ps1 must treat release-archive checksums as
backward-compatible rollout metadata:
- If
<archive>.sha256exists, verify it and fail the install on malformed checksum data or checksum mismatch. - If the sidecar is missing for a legacy/current release, warn and continue by default.
- If
MESH_LLM_REQUIRE_CHECKSUM=1is set, a missing sidecar is fatal.
Do not change installer behavior to hard-require sidecars by default unless the release policy also guarantees every supported/pinned release and alternate install repo has matching checksum assets.
What NOT to add
- No
api_key_tokenfeature; it was explicitly rejected and removed in v0.26.0. - No domain logic in
mesh/crates/mesh-llm/src/. Keep that crate to CLI dispatch wiring; put domain behavior inmesh-llm-host-runtimeor a narrower peer crate.
Trending
Quiet since April.about the whole repository
Who's talking about michaelneale/mesh-llm
- A Hacker News story“Pool spare GPU capacity to run LLMs at larger scale”Hacker News · Mar 24, 2026 · 11 points
- @rusttrending.bsky.social“michaelneale / mesh-llm: reference impl with llama.cpp compiled to distributed inference across machines, …”Bluesky · Apr 11, 2026 · 2 likes
- @yug1224.com“複数のLLMを連携させてタスクをこなすための分散型エージェントフレームワークらしい 複雑なワークフローを構築する際に役立ちそうかな yug1224 starred michaelneale/mesh-llm…”Bluesky · Apr 8, 2026 · 1 likes
- Mesh-LLM/mesh-llm“Add mesh-llm MoE planning, analysis, and ranking contribution commands”GitHub · Apr 11, 2026
- Mesh-LLM/mesh-llm“Simplify model for node states”GitHub · Apr 10, 2026
The biggest 5 of 18 mentions linking to the repository that our crawl found. Each line is their own headline.
See all 18
Talked about on GitHub, Bluesky and Hacker News (18 times).
On GitHub · 15
- Apr 11, 2026Add mesh-llm MoE planning, analysis, and ranking contribution commands — Mesh-LLM/mesh-llm0 reactions · 1 comment
- Apr 10, 2026Simplify model for node states — Mesh-LLM/mesh-llm0 reactions · 2 comments
- Apr 10, 2026revise mesh publication rules — Mesh-LLM/mesh-llm0 reactions · 1 comment
- Apr 5, 2026Roll out config as local node config first, then reconcile mesh-wide desired state — Mesh-LLM/mesh-llm0 reactions · 2 comments
- Apr 3, 2026CommitLLM sumi capture: working on Apple Silicon Q8_0 — michaelneale/llama.cpp0 reactions
10 more on GitHub
- Apr 2, 2026Add hardware runtime status enrichment without changing model metadata sources — Mesh-LLM/mesh-llm0 reactions
- Apr 2, 2026Design owner identity propagation and direct verification — Mesh-LLM/mesh-llm0 reactions · 4 comments
- Apr 2, 2026Design owner keystore and Rust signed+encrypted message primitives — Mesh-LLM/mesh-llm0 reactions
- Apr 2, 2026Track splitting PR #130 into smaller rollout PRs — Mesh-LLM/mesh-llm0 reactions · 2 comments
- Apr 2, 2026research: mesh-llm integration — p2p inference mesh + model sharding under obol-stack economic layer — ObolNetwork/obol-stack0 reactions
- Apr 2, 2026[WIP] Make PR 103 mergable on top of PR 127 — Mesh-LLM/mesh-llm0 reactions
- Apr 2, 2026refactor: decompose mesh.rs and app/mod.rs into focused submodules — Mesh-LLM/mesh-llm0 reactions · 1 comment
- Mar 28, 2026Autoupdater — Mesh-LLM/mesh-llm0 reactions
- Mar 27, 2026Add a staged auto-updater for release bundles — Mesh-LLM/mesh-llm0 reactions
- Mar 27, 2026Add generic bulk transfer support to mesh plugins — Mesh-LLM/mesh-llm0 reactions
On Bluesky · 2
- Apr 11, 2026michaelneale / mesh-llm: reference impl with llama.cpp compiled to distributed inference across machines, with real end to end demo ★720… — @rusttrending.bsky.social2 likes and reposts
- Apr 8, 2026複数のLLMを連携させてタスクをこなすための分散型エージェントフレームワークらしい 複雑なワークフローを構築する際に役立ちそうかな yug1224 starred michaelneale/mesh-llm… — @yug1224.com1 likes and repost
On Hacker News · 1
- Mar 24, 2026Pool spare GPU capacity to run LLMs at larger scale11 points · 3 comments
Other versions1 project uses a version of this.
Word for word · 1
- Mesh-LLM/mesh-llm★ 3.5k100% same
Edited · 0
None found.
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 28,693 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository32 other files it gives its agents.
- AGENTS.mdAGENTS.md
- .github/AGENTS.mdAGENTS.md
- skippy/AGENTS.mdAGENTS.md
- benchmark-tuneSkill
- config-settings-managementSkill
- connect-agentsSkill
- deploy-linux-gpuSkill
- deploy-macosSkill
- deploy-windowsSkill
- hf-bf16-gguf-conversion-jobsSkill
- hf-gguf-quant-jobsSkill
- hf-layer-package-jobsSkill
- hf-quant-and-layer-package-jobsSkill
- kv-tool-loop-stabilitySkill
- llama-patch-changesSkill
- llama-stage-patch-changesSkill
- manage-ciSkill
- mesh-joinSkill
- metrics-serverSkill
- plugin-web-ui-extensionSkill
- release-notesSkill
- release-validationSkill
- remote-observable-processSkill
- skippy-cache-family-benchSkill
- skippy-correctnessSkill
- skippy-family-certificationSkill
- skippy-metricsSkill
- skippy-model-packageSkill
- skippy-promptSkill
- skippy-servingSkill
- skippy-spec-benchSkill
- telemetry-privacy-reviewSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
Reviews can't be read right now.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

