Skip to main content

NoiseWeaver

A rebrandable, polyglot platform for AI asset pipelines — the open, generic layer you run around a pipeline. It provides the parts every studio needs and none of the parts that are anyone's secret.

NoiseWeaver contains no pipeline: the stages, recipes, model wiring, and prompts are a plugin written by whoever uses it. The dependency arrow points one way — plugins import noiseweaver; noiseweaver never imports a plugin, a specific compute daemon, or a storage backend it merely orchestrates. That keeps the platform free of proprietary IP and able to stand on its own (and to be shared between studios).

The four pillars (+ the shell)

Module What it is
noiseweaver.build A generic content-addressed staged-build engine over JSON specs — a mini build system: a spec document → a Merkle DAG → CAS staging → variant ledger + tombstones.
noiseweaver.compute A Tool × Platform compute schedulerwhat API you speak (ComfyUI, or a plugin's own client) is orthogonal to where it runs (local, RunPod, k8s); placed Kubernetes-style by matching requirements ↔ offers.
noiseweaver.storage / .cas A storage/repo abstraction (local folder | Perforce stream) + an immutable content-addressed store. The pipeline only ever sees a local path.
noiseweaver.pod Pod transport — discover a RunPod's SSH, hold a persistent tunnel, talk to ComfyUI over HTTP, and run a service on a rented pod (PodService).
noiseweaver.shell / .plugin A rebrandable Gradio shell + the small plugin contract that mounts a pipeline into it.

Everything is pure-Python and fully unit-tested with no daemon, pod, cluster, or Perforce server (70 tests) — the external pieces are injected and faked.


Build engine — noiseweaver.build

A spec is a JSON document ({type, stages: {stage: params}}). The engine knows how to chain, hash, store, and cache stages into a Merkle DAG where every parameter branch is content-addressed and cheaply cached; it knows nothing about what the stages do. A plugin injects a Pipeline (the stage names + per-stage normalizers, recipe versions, etc.) and the executors.

from noiseweaver.build import Spec, SpecFormat, Pipeline, Staging, Index, build

fmt = SpecFormat(suffix=".demo.json")                  # your on-disk format + a validator
pipe = Pipeline(stages=("gen", "post"), normalize=my_normalize,
                recipe_versions={"gen": "g/1"}, artifact_names={"gen": "gen.png"})

spec = Spec.load("proj/thing.demo.json", fmt, root="…")
build(spec, pipe, {"gen": gen_executor, "post": post_executor},
      staging=Staging("~/.cache/staging"), index=Index("~/.cache/staging"))
# unchanged stages are cache hits; changing one param recomputes only it + its descendants.

Subclass Spec to bind your format once (so callers keep a clean MySpec.load(path)) — e.g. a plugin binds its own .<type>.json format + validator + recipe versions in one place.

Compute — noiseweaver.compute

Two orthogonal axes, composed into a Placement = (Tool, Platform, ExecutionMode) the scheduler resolves Kubernetes-style:

  • Tool — the API you speak (ComfyUITool HTTP ships built in; a plugin adds its own, e.g. an NDJSON/UDS local-daemon client). Platform-agnostic; one client whether the service is local, on a pod, or in a cluster.
  • Platform — where it's provisioned and reached (LocalPlatform, ExternalPlatform, RemotePlatform). Tool-agnostic; RunPod/k8s lifecycle is injected once and shared across tools.
  • Requirements ↔ Offers — a tool declares Requirements({os, arch, accelerator, vram}); a platform declares Offers; the scheduler only places a tool where the offers satisfy it (an MLX tool requires {macos, mlx} so it never schedules off a Mac; a CUDA workload never lands on a Mac).
  • Execution modesSERVICE (a persistent endpoint, many calls) and JOB (submit → result).
from noiseweaver.compute import (
    Scheduler, ComfyUITool, LocalPlatform, RemotePlatform, Offers,
    ImageRequest, text_to_image,
)

sched = Scheduler(
    # ComfyUITool ships with NoiseWeaver; MyLocalDaemonTool is your plugin's own Tool.
    tools=[MyLocalDaemonTool(), ComfyUITool()],
    platforms=[LocalPlatform(),
               RemotePlatform("runpod", Offers("linux", "x86_64", frozenset({"cuda"}), 80),
                              acquire=my_pod_acquire)],
)
# picks the local daemon for a Mac-hostable weight, else comfyui@runpod — by matching, not branches.
result = text_to_image(sched, ImageRequest(prompt="…", output="/tmp/out.png",
                                           model="flux", variant="flux1-schnell"))

Storage — noiseweaver.storage / noiseweaver.cas

Point each logical repo at a local folder or a Perforce stream; the pipeline only sees a local path (a synced Perforce stream is a folder), and NoiseWeaver manages the Perforce workspace (client spec + login) and sync/submit.

from noiseweaver.config import NoiseWeaverConfig

cfg = NoiseWeaverConfig.load()        # reads noiseweaver.toml; P4 password from $P4PASSWD
assets = cfg.repo("assets")
assets.ensure_ready()                 # provisions the p4 client + login (idempotent)
assets.sync()                         # `p4 sync` (no-op for a local repo)
root = assets.root()                  # the local path your pipeline reads/writes
assets.submit([root / "new.fbx"], "add new asset")

noiseweaver.cas.CasStore is the immutable, content-addressed blob+manifest store the build engine's staging is built on (hardlink materialization, safe to back up as a plain folder).

To back a repo with a local, password-protected, checkpoint-backed Perforce server (and how to fold-back-up Perforce safely with Backblaze), see docs/perforce-local-server.md.

Pod — noiseweaver.pod

The generic pod transport the compute backends provision onto: discover_endpoint (RunPod GraphQL direct-SSH), PodSSH (persistent control SSH + local port-forward), ComfyUIClient (HTTP + UI→API workflow conversion), and PodService — the reusable lifecycle: discover → connect → optional deploy hook → start a foreground command → forward its port → wait until ready → tear down on close. Discovery + the SSH class are injectable, so the whole lifecycle unit-tests with no pod.

The shell — noiseweaver.shell / noiseweaver.plugin

from noiseweaver.shell import launch
launch(MyPipelinePlugin(), my_config)    # serves the rebranded UI on the LAN

A plugin implements three methods — branding(), build_header(config), tabs(). The shell owns the chrome; set NOISEWEAVER_TITLE / NOISEWEAVER_SUBTITLE to rebrand without code. See noiseweaver/plugin.py.

Configuration

noiseweaver.toml (path via NOISEWEAVER_CONFIG) — repos + the compute policy; secrets come from the environment, never the file. See noiseweaver.example.toml.

[repos.assets]
kind   = "perforce"         # or "local"
stream = "//assets/main"
client = "assets-mac-you"
root   = "~/p4/assets"

[compute]
runpod = true               # offload backends available to the scheduler
k8s    = false
prefer = ["local", "runpod", "k8s"]

Develop

uv sync --extra dev
uv run pytest        # 70 tests, no external services
uv run ruff check

MIT licensed.

Release files for noiseweaver 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for noiseweaver 0.1.0
File Size Uploaded
noiseweaver-0.1.0.tar.gz 169.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for noiseweaver 0.1.0
File Interpreter ABI Platform
noiseweaver-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 224.9 kB

Release files / noiseweaver-0.1.0.tar.gz

Download URL noiseweaver-0.1.0.tar.gz
Size 169.3 kB
Tags Source
SHA-256 checksum
How to use checksums
72fbcdc95051fe9cffbbe9e251ef065e0d7024db922e634b6ef5bd39ae8a1d21
BLAKE2b-256 checksum
How to use checksums
a2d34a6207c599912e3ecc202b8dcf7be104c00d4190898c06f02d9ccd792d58
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 30, 2026.

Transparency log

Release files / noiseweaver-0.1.0-py3-none-any.whl

Download URL noiseweaver-0.1.0-py3-none-any.whl
Size 55.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
08a3a7223a71c6c93668abf051c4aff0ab6c7f6afe55d91732d8b1ac3cbf8eb2
BLAKE2b-256 checksum
How to use checksums
b9a1d970025149e63d42c39fdb59574e94bdd0bcd48d50fc349f4e622b40125b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 30, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page