nodetool-mlx 0.7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (40) hide show
  1. nodetool_mlx-0.7.0/.github/workflows/ci.yml +122 -0
  2. nodetool_mlx-0.7.0/.github/workflows/publish-wheel.yml +230 -0
  3. nodetool_mlx-0.7.0/.gitignore +56 -0
  4. nodetool_mlx-0.7.0/PKG-INFO +219 -0
  5. nodetool_mlx-0.7.0/README.md +191 -0
  6. nodetool_mlx-0.7.0/pyproject.toml +72 -0
  7. nodetool_mlx-0.7.0/requirements-dev.txt +13 -0
  8. nodetool_mlx-0.7.0/src/nodetool/mlx/__init__.py +5 -0
  9. nodetool_mlx-0.7.0/src/nodetool/mlx/flux_model_loader.py +445 -0
  10. nodetool_mlx-0.7.0/src/nodetool/mlx/mlx_provider.py +3015 -0
  11. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/LICENSE +21 -0
  12. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/NOTICE.md +23 -0
  13. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/__init__.py +24 -0
  14. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/defs/__init__.py +0 -0
  15. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/defs/dit_mlx.py +344 -0
  16. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/defs/dit_mlx_medium.py +458 -0
  17. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/defs/sa3_pipeline.py +199 -0
  18. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/defs/same_l_decoder.py +345 -0
  19. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/defs/same_l_encoder.py +146 -0
  20. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/defs/same_s_decoder.py +294 -0
  21. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/defs/same_s_encoder.py +161 -0
  22. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/defs/t5gemma_mlx.py +313 -0
  23. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/pipeline.py +386 -0
  24. nodetool_mlx-0.7.0/src/nodetool/mlx/stable_audio_3/weights.py +64 -0
  25. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/_hf_cache.py +55 -0
  26. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/automatic_speech_recognition.py +184 -0
  27. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/image_to_image.py +3199 -0
  28. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/image_to_text.py +219 -0
  29. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/speech_enhancement.py +252 -0
  30. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/speech_to_text.py +411 -0
  31. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/text_generation.py +245 -0
  32. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/text_to_audio.py +372 -0
  33. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/text_to_image.py +336 -0
  34. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/text_to_music.py +729 -0
  35. nodetool_mlx-0.7.0/src/nodetool/nodes/mlx/text_to_speech.py +1464 -0
  36. nodetool_mlx-0.7.0/src/nodetool/package_metadata/nodetool-mlx.json +10105 -0
  37. nodetool_mlx-0.7.0/tests/nodes/mlx/test_text_to_music.py +156 -0
  38. nodetool_mlx-0.7.0/tests/test_audio_nodes.py +533 -0
  39. nodetool_mlx-0.7.0/tests/test_image_nodes.py +214 -0
  40. nodetool_mlx-0.7.0/tests/test_package_metadata.py +84 -0
@@ -0,0 +1,122 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches:
7
+ - main
8
+ workflow_dispatch:
9
+
10
+ # A new push to a PR makes the in-flight run obsolete.
11
+ concurrency:
12
+ group: ci-${{ github.workflow }}-${{ github.ref }}
13
+ cancel-in-progress: true
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ lint:
20
+ name: Lint and format
21
+ runs-on: ubuntu-latest
22
+ timeout-minutes: 10
23
+ steps:
24
+ - uses: actions/checkout@v6
25
+
26
+ - uses: actions/setup-python@v6
27
+ with:
28
+ python-version: "3.11"
29
+ cache: pip
30
+
31
+ - name: Install linters
32
+ # Pinned: an unpinned linter turns an upstream release into a red build
33
+ # on an unrelated PR. Bump deliberately, fixing any new findings in the
34
+ # same change. Keep in sync with requirements-dev.txt.
35
+ run: pip install "ruff==0.15.8" "black==26.3.1"
36
+
37
+ - name: ruff
38
+ run: ruff check .
39
+
40
+ - name: black
41
+ run: black --check --diff .
42
+
43
+ # The MLX runtimes (mlx, mflux, mlx-audio, ...) are Apple Silicon only, so the
44
+ # bulk of the suite is written to run without them and this job installs the
45
+ # package with --no-deps. It is the fast signal on every push, and it also
46
+ # covers the "node modules import without the MLX stack" property that the
47
+ # package metadata scanner relies on.
48
+ test-linux:
49
+ name: Test (linux, no MLX runtime)
50
+ runs-on: ubuntu-latest
51
+ timeout-minutes: 20
52
+ strategy:
53
+ fail-fast: false
54
+ matrix:
55
+ python-version: ["3.11", "3.12"]
56
+ steps:
57
+ - uses: actions/checkout@v6
58
+
59
+ - uses: actions/setup-python@v6
60
+ with:
61
+ python-version: ${{ matrix.python-version }}
62
+ cache: pip
63
+
64
+ - name: Install nodetool-core and test dependencies
65
+ run: |
66
+ pip install --upgrade pip
67
+ pip install "nodetool-core>=0.7.0"
68
+ pip install pytest pytest-asyncio pytest-cov
69
+
70
+ - name: Install this package without the Apple-Silicon-only dependencies
71
+ run: pip install --no-deps -e .
72
+
73
+ - name: Run tests
74
+ # Tests needing mflux / mlx-audio skip themselves via importorskip.
75
+ run: pytest tests -q
76
+
77
+ # The real thing: Apple Silicon runners install the full dependency set, so
78
+ # nothing is skipped here. Slower and heavier, hence a single Python version.
79
+ test-macos:
80
+ name: Test (macOS, full MLX runtime)
81
+ runs-on: macos-14
82
+ timeout-minutes: 45
83
+ steps:
84
+ - uses: actions/checkout@v6
85
+
86
+ - uses: actions/setup-python@v6
87
+ with:
88
+ python-version: "3.11"
89
+ cache: pip
90
+
91
+ - name: Install package with all dependencies
92
+ run: |
93
+ pip install --upgrade pip
94
+ pip install -e .
95
+ pip install pytest pytest-asyncio pytest-cov
96
+
97
+ - name: Show installed MLX stack
98
+ run: pip list | grep -Ei "^(mlx|mflux|nodetool)" || true
99
+
100
+ - name: Run tests
101
+ run: pytest tests -q
102
+
103
+ build:
104
+ name: Build wheel
105
+ runs-on: ubuntu-latest
106
+ timeout-minutes: 10
107
+ steps:
108
+ - uses: actions/checkout@v6
109
+
110
+ - uses: actions/setup-python@v6
111
+ with:
112
+ python-version: "3.11"
113
+ cache: pip
114
+
115
+ - name: Install build tooling
116
+ run: pip install --upgrade pip build twine
117
+
118
+ - name: Build sdist and wheel
119
+ run: python -m build
120
+
121
+ - name: Check distributions
122
+ run: twine check dist/*
@@ -0,0 +1,230 @@
1
+ name: Build and Publish Wheel
2
+
3
+ on:
4
+ # Trigger on version tags
5
+ push:
6
+ tags:
7
+ - "v*.*.*"
8
+
9
+ # Manual trigger for testing
10
+ workflow_dispatch:
11
+ inputs:
12
+ version:
13
+ description: "Version to release (e.g., 0.6.0)"
14
+ required: true
15
+ type: string
16
+ prerelease:
17
+ description: "Mark as prerelease"
18
+ required: false
19
+ default: false
20
+ type: boolean
21
+ publish_pypi:
22
+ description: "Also publish to PyPI / TestPyPI"
23
+ required: false
24
+ default: "none"
25
+ type: choice
26
+ options:
27
+ - none
28
+ - testpypi
29
+ - pypi
30
+
31
+ env:
32
+ PACKAGE_NAME: ${{ github.event.repository.name }} # e.g., "nodetool-base"
33
+
34
+ jobs:
35
+ validate:
36
+ runs-on: ubuntu-latest
37
+ outputs:
38
+ version: ${{ steps.get-version.outputs.version }}
39
+ tag-name: ${{ steps.get-version.outputs.tag-name }}
40
+ is-prerelease: ${{ steps.get-version.outputs.is-prerelease }}
41
+ steps:
42
+ - name: Get version from tag or input
43
+ id: get-version
44
+ run: |
45
+ if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
46
+ VERSION="${{ github.event.inputs.version }}"
47
+ TAG_NAME="v${VERSION}"
48
+ IS_PRERELEASE="${{ github.event.inputs.prerelease }}"
49
+ else
50
+ TAG_NAME="${{ github.ref_name }}"
51
+ VERSION="${TAG_NAME#v}"
52
+ IS_PRERELEASE="false"
53
+ fi
54
+
55
+ echo "version=$VERSION" >> $GITHUB_OUTPUT
56
+ echo "tag-name=$TAG_NAME" >> $GITHUB_OUTPUT
57
+ echo "is-prerelease=$IS_PRERELEASE" >> $GITHUB_OUTPUT
58
+
59
+ echo "📋 Version: $VERSION"
60
+ echo "🏷️ Tag: $TAG_NAME"
61
+ echo "🔄 Prerelease: $IS_PRERELEASE"
62
+
63
+ build-wheel:
64
+ needs: validate
65
+ runs-on: ubuntu-latest
66
+ steps:
67
+ - name: Checkout code
68
+ uses: actions/checkout@v6
69
+ with:
70
+ ref: ${{ needs.validate.outputs.tag-name }}
71
+
72
+ - name: Set up Python
73
+ uses: actions/setup-python@v6
74
+ with:
75
+ python-version: "3.11"
76
+
77
+ - name: Install build dependencies
78
+ run: |
79
+ pip install --upgrade pip
80
+ pip install build hatchling twine
81
+
82
+ - name: Download build helper
83
+ run: |
84
+ curl -fsSL https://raw.githubusercontent.com/nodetool-ai/nodetool-core/main/build.py -o build.py
85
+
86
+ - name: Build wheel
87
+ run: |
88
+ echo "🏗️ Building wheel for ${{ env.PACKAGE_NAME }}"
89
+ python build.py build-wheel --expected-version "${{ needs.validate.outputs.version }}"
90
+
91
+ - name: Validate wheel
92
+ run: |
93
+ python build.py validate-wheel
94
+
95
+ - name: Upload wheel artifact
96
+ uses: actions/upload-artifact@v7
97
+ with:
98
+ name: wheel-${{ env.PACKAGE_NAME }}-${{ needs.validate.outputs.version }}
99
+ path: |
100
+ dist/*.whl
101
+ dist/*.whl.metadata
102
+ retention-days: 30
103
+
104
+ create-release:
105
+ needs: [validate, build-wheel]
106
+ runs-on: ubuntu-latest
107
+ permissions:
108
+ contents: write
109
+ steps:
110
+ - name: Checkout code
111
+ uses: actions/checkout@v6
112
+ with:
113
+ ref: ${{ needs.validate.outputs.tag-name }}
114
+
115
+ - name: Download build helper
116
+ run: |
117
+ curl -fsSL https://raw.githubusercontent.com/nodetool-ai/nodetool-core/main/build.py -o build.py
118
+
119
+ - name: Download wheel artifact
120
+ uses: actions/download-artifact@v8
121
+ with:
122
+ name: wheel-${{ env.PACKAGE_NAME }}-${{ needs.validate.outputs.version }}
123
+ path: dist/
124
+
125
+ - name: Generate release notes
126
+ run: |
127
+ python build.py release-notes \
128
+ --package "${{ env.PACKAGE_NAME }}" \
129
+ --version "${{ needs.validate.outputs.version }}" \
130
+ --tag "${{ needs.validate.outputs.tag-name }}" \
131
+ --repository "${{ github.repository }}" \
132
+ --server-url "${{ github.server_url }}"
133
+
134
+ - name: Create GitHub Release
135
+ uses: softprops/action-gh-release@v1
136
+ with:
137
+ tag_name: ${{ needs.validate.outputs.tag-name }}
138
+ name: "${{ env.PACKAGE_NAME }} v${{ needs.validate.outputs.version }}"
139
+ body_path: release_notes.md
140
+ files: |
141
+ dist/*.whl
142
+ dist/*.whl.metadata
143
+ draft: false
144
+ prerelease: ${{ needs.validate.outputs.is-prerelease }}
145
+ generate_release_notes: true
146
+ env:
147
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
148
+
149
+ - name: Notify registry
150
+ if: success()
151
+ env:
152
+ REGISTRY_UPDATE_TOKEN: ${{ secrets.REGISTRY_UPDATE_TOKEN }}
153
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
154
+ run: |
155
+ python build.py notify-registry \
156
+ --package "${{ env.PACKAGE_NAME }}" \
157
+ --version "${{ needs.validate.outputs.version }}" \
158
+ --tag "${{ needs.validate.outputs.tag-name }}" \
159
+ --repository "${{ github.repository }}" \
160
+ --server-url "${{ github.server_url }}"
161
+
162
+ - name: Create success summary
163
+ run: |
164
+ python build.py summary \
165
+ --package "${{ env.PACKAGE_NAME }}" \
166
+ --version "${{ needs.validate.outputs.version }}" \
167
+ --tag "${{ needs.validate.outputs.tag-name }}" \
168
+ --repository "${{ github.repository }}" \
169
+ --server-url "${{ github.server_url }}"
170
+
171
+ # Publish to PyPI via Trusted Publishing (OIDC). No stored tokens.
172
+ # Runs on every v*.*.* tag push, or a manual run with publish_pypi=pypi.
173
+ # PyPI pending publisher: workflow publish-wheel.yml, environment pypi.
174
+ publish-pypi:
175
+ needs: [validate, build-wheel]
176
+ if: github.event_name == 'push' || github.event.inputs.publish_pypi == 'pypi'
177
+ runs-on: ubuntu-latest
178
+ environment:
179
+ name: pypi
180
+ url: https://pypi.org/project/nodetool-mlx/
181
+ permissions:
182
+ id-token: write # required for OIDC trusted publishing
183
+ steps:
184
+ - name: Checkout code
185
+ uses: actions/checkout@v6
186
+ with:
187
+ ref: ${{ needs.validate.outputs.tag-name }}
188
+
189
+ - name: Install uv
190
+ uses: astral-sh/setup-uv@v5
191
+ with:
192
+ python-version: "3.11"
193
+
194
+ - name: Build sdist + wheel
195
+ run: uv build
196
+
197
+ - name: Validate distributions
198
+ run: uvx twine check dist/*
199
+
200
+ - name: Publish to PyPI
201
+ uses: pypa/gh-action-pypi-publish@release/v1
202
+
203
+ # Manual-only TestPyPI dry run (publish_pypi=testpypi).
204
+ publish-testpypi:
205
+ needs: [validate, build-wheel]
206
+ if: github.event_name == 'workflow_dispatch' && github.event.inputs.publish_pypi == 'testpypi'
207
+ runs-on: ubuntu-latest
208
+ environment:
209
+ name: testpypi
210
+ url: https://test.pypi.org/project/nodetool-mlx/
211
+ permissions:
212
+ id-token: write
213
+ steps:
214
+ - name: Checkout code
215
+ uses: actions/checkout@v6
216
+ with:
217
+ ref: ${{ needs.validate.outputs.tag-name }}
218
+
219
+ - name: Install uv
220
+ uses: astral-sh/setup-uv@v5
221
+ with:
222
+ python-version: "3.11"
223
+
224
+ - name: Build sdist + wheel
225
+ run: uv build
226
+
227
+ - name: Publish to TestPyPI
228
+ uses: pypa/gh-action-pypi-publish@release/v1
229
+ with:
230
+ repository-url: https://test.pypi.org/legacy/
@@ -0,0 +1,56 @@
1
+ __pycache__
2
+ *.pyc
3
+ *.pyo
4
+ *.dmypy.json
5
+ *.jar
6
+ .mypy_cache
7
+ *.egg-info
8
+ *.egg
9
+ *.pth
10
+ *.torchscript
11
+ *.ckpt
12
+ *.gguf
13
+ *.pt
14
+ *.pth
15
+ *.safetensors
16
+ build/
17
+ dist/
18
+ electron/apps/build/
19
+ electron/dist/
20
+ electron/dist-web/
21
+ electron/dist-electron/
22
+ # Temporary build files
23
+ .tmp/
24
+ __notebooks/
25
+ package/
26
+ postgres_data/
27
+ .ipynb_checkpoints
28
+ .huggingface
29
+
30
+ .bin
31
+ .vite
32
+ .venv
33
+ node_modules
34
+ docs.chromadb
35
+
36
+ # Cache
37
+ .cache
38
+ .eslintcache
39
+
40
+ # Testing
41
+ /coverage
42
+ *.lcov
43
+
44
+ # Environment variables
45
+ *.override.env
46
+
47
+ # macOS
48
+ # https://github.com/github/gitignore/blob/master/Global/macOS.gitignore
49
+ .DS_Store
50
+
51
+ .env
52
+ cert.pem
53
+ key.pem
54
+ .aider*
55
+
56
+ .codegpt
@@ -0,0 +1,219 @@
1
+ Metadata-Version: 2.5
2
+ Name: nodetool-mlx
3
+ Version: 0.7.0
4
+ Summary: Apple Silicon MLX nodes for Nodetool
5
+ Author-email: Matthias Georgi <matti.georgi@gmail.com>
6
+ Requires-Python: >=3.11
7
+ Requires-Dist: huggingface-hub>=0.24.6
8
+ Requires-Dist: mflux>=0.18.1
9
+ Requires-Dist: mlx-audio>=0.4.4
10
+ Requires-Dist: mlx-lm>=0.31.3
11
+ Requires-Dist: mlx-vlm>=0.4.4
12
+ Requires-Dist: mlx-whisper>=0.4.3
13
+ Requires-Dist: mlx>=0.30
14
+ Requires-Dist: nodetool-core>=0.7.0
15
+ Requires-Dist: numba>=0.62.1
16
+ Requires-Dist: numpy>=1.26
17
+ Requires-Dist: sentencepiece>=0.2
18
+ Provides-Extra: dev
19
+ Requires-Dist: black>=24.10.0; extra == 'dev'
20
+ Requires-Dist: mypy>=1.9.0; extra == 'dev'
21
+ Requires-Dist: pytest-asyncio>=0.23.5; extra == 'dev'
22
+ Requires-Dist: pytest-cov>=4.1.0; extra == 'dev'
23
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
24
+ Requires-Dist: ruff>=0.3.4; extra == 'dev'
25
+ Provides-Extra: stable
26
+ Requires-Dist: nodetool-core==0.7.0; extra == 'stable'
27
+ Description-Content-Type: text/markdown
28
+
29
+ # nodetool-mlx
30
+
31
+ [![CI](https://github.com/nodetool-ai/nodetool-mlx/actions/workflows/ci.yml/badge.svg)](https://github.com/nodetool-ai/nodetool-mlx/actions/workflows/ci.yml)
32
+
33
+ High-performance MLX-native nodes for [Nodetool](https://github.com/nodetool-ai/nodetool) on Apple Silicon. This package wraps the community MLX implementations of Whisper, Kokoro/Sesame TTS, MFlux FLUX.1 image generation, and Stability AI's Stable Audio 3 so you can run state-of-the-art audio and vision workflows locally on macOS.
34
+
35
+ ## Why nodetool-mlx?
36
+
37
+ - **Local-first** – keep data on-device by running speech, TTS, and image models without cloud calls
38
+ - **Optimised for Apple Silicon** – uses MLX kernels and quantized checkpoints to achieve strong throughput on M-series chips
39
+ - **Drop-in nodes** – integrates seamlessly with the Nodetool graph editor and `nodetool-core` runtime
40
+
41
+ ## Provided Nodes
42
+
43
+ All nodes live under `src/nodetool/nodes/mlx`. Audio nodes wrap the
44
+ [`mlx-audio`](https://github.com/Blaizzy/mlx-audio) library.
45
+
46
+ ### Text-to-Speech (`mlx.text_to_speech`)
47
+
48
+ - `KokoroTTS` – fast multilingual TTS with 54 voice presets
49
+ - `SesameTTS` – CSM voice cloning from a reference clip
50
+ - `SparkTTS` – controllable speed / pitch / gender presets
51
+ - `Qwen3TTS` – multilingual TTS with speaker voices and voice design
52
+ - `KittenTTS` – compact, edge-friendly English voices
53
+ - `DiaTTS` – dialogue TTS with `[S1]` / `[S2]` speaker tags
54
+ - `OuteTTS` – efficient multilingual TTS with optional cloning
55
+ - `OmniVoiceTTS` – zero-shot multilingual (646+ languages)
56
+ - `MeloTTS` – lightweight VITS2 English accents
57
+ - `VoxtralTTS` – Mistral's multilingual TTS with voice presets
58
+ - `ChatterboxTTS` – expressive TTS with exaggeration control and cloning
59
+ - `HiggsAudioTTS` – conversational TTS with zero-shot cloning
60
+ - `LongCatAudioTTS` – diffusion TTS with zero-shot cloning
61
+ - `MLXTextToSpeech` – generic node that runs any `mlx-audio` TTS repo id
62
+
63
+ ### Speech-to-Text (`mlx.automatic_speech_recognition`, `mlx.speech_to_text`)
64
+
65
+ - `Whisper` – MLX Whisper transcription with optional word timestamps
66
+ - `Parakeet` – NVIDIA Parakeet high-accuracy multilingual ASR
67
+ - `Qwen3ASR` – Alibaba's multilingual ASR with long-form chunking
68
+ - `Qwen3ForcedAligner` – word-level timestamp alignment for a known transcript
69
+ - `MLXSpeechToText` – generic node that runs any `mlx-audio` STT repo id
70
+
71
+ ### Speech Enhancement (`mlx.speech_enhancement`)
72
+
73
+ - `DeepFilterNet` – real-time noise suppression (v1/v2/v3) at 48 kHz
74
+ - `MossFormer2` – high-quality 48 kHz speech enhancement
75
+
76
+ ### Image (`mlx.text_to_image`, `mlx.image_to_image`)
77
+
78
+ - `MFlux` and the `MFlux*` family – FLUX.1 / Qwen-Image / Z-Image / FIBO generation
79
+ and editing via the MFlux project (supports quantized models)
80
+
81
+ ### Image-to-Text (`mlx.image_to_text`)
82
+
83
+ - `MLXVisionLanguage` – image captioning, visual Q&A, and OCR via MLX vision-language models (Qwen3-VL, Gemma 4)
84
+
85
+ ### Text-to-Audio (`mlx.text_to_audio`)
86
+
87
+ - `StableAudio3` – text-to-audio music & sound effects with [Stable Audio 3](https://github.com/Stability-AI/stable-audio-3) (44.1 kHz stereo)
88
+ - `StableAudio3AudioToAudio` – prompt-guided variations of an input clip
89
+ - `StableAudio3Inpaint` – regenerate a time range inside an audio clip
90
+
91
+ ### Text-to-Music (`mlx.text_to_music`)
92
+
93
+ - `ACEStepMusicGeneration` – local text-to-music generation with [ACE-Step 1.5](https://github.com/ace-step/ACE-Step-1.5) (prompt + lyrics → full songs)
94
+ - `ACEStepSongPlanner` – use the ACE-Step 5Hz language model to turn an idea into a caption, lyrics and musical metadata
95
+
96
+ ### Text (`mlx.text_generation`)
97
+
98
+ - `TextGeneration` – local LLM text generation via `mlx-lm`
99
+
100
+ ### Stable Audio 3
101
+
102
+ The Stable Audio 3 nodes run Stability AI's optimized MLX implementation (no PyTorch at
103
+ runtime), vendored under `nodetool.mlx.stable_audio_3` (MIT licensed — see that folder's
104
+ `LICENSE` and `NOTICE.md`). Three DiT variants are available via the **model** field:
105
+
106
+ - `sm-music` (50M) – fast music generation
107
+ - `sm-sfx` (50M) – sound effects
108
+ - `medium` (1.4B) – higher-fidelity music
109
+
110
+ Weights are pulled on demand from the Hugging Face repo
111
+ [`stabilityai/stable-audio-3-optimized`](https://huggingface.co/stabilityai/stable-audio-3-optimized)
112
+ (only the `MLX/*` files) and cached locally; you can also pre-download them from the
113
+ Models Manager.
114
+
115
+ ### ACE-Step 1.5 (music generation)
116
+
117
+ The ACE-Step nodes wrap the official [ACE-Step 1.5](https://github.com/ace-step/ACE-Step-1.5)
118
+ project, which uses MLX for the diffusion transformer, VAE and language model on
119
+ Apple Silicon. ACE-Step 1.5 is **not** distributed on PyPI (the `ace-step` package
120
+ there is the older 1.0 release), so it must be installed separately:
121
+
122
+ ```bash
123
+ git clone https://github.com/ace-step/ACE-Step-1.5.git
124
+ cd ACE-Step-1.5
125
+ uv sync # installs the macOS/MLX dependencies
126
+ ```
127
+
128
+ Install it into the same environment as `nodetool-mlx`. If the package is missing,
129
+ the nodes raise a clear error pointing back to the repository.
130
+
131
+ Checkpoints are downloaded automatically from HuggingFace on first use into
132
+ `~/.cache/nodetool/acestep/checkpoints` (override with the `ACESTEP_CHECKPOINTS_DIR`
133
+ environment variable). The main bundle `ACE-Step/Ace-Step1.5` includes the VAE, the
134
+ turbo DiT and the 1.7B planner LM; additional DiT and LM checkpoints are listed as
135
+ recommended models on each node.
136
+
137
+
138
+ ## Requirements
139
+
140
+ - macOS 14+ on Apple Silicon (MLX currently supports Apple hardware only)
141
+ - Python 3.11
142
+ - [nodetool-core](https://github.com/nodetool-ai/nodetool-core) v0.6.0+
143
+ - Required MLX checkpoints managed via the Nodetool Models Manager (see [_Managing Models_](#managing-models))
144
+
145
+ ## Installation
146
+
147
+ ### From the Nodetool UI
148
+
149
+ 1. Open Nodetool → **Tools ▸ Packages**
150
+ 2. Install the `nodetool-mlx` pack from the package registry
151
+ 3. Nodetool will handle dependencies and expose the MLX nodes in the graph editor once installed
152
+
153
+ ### From source (development)
154
+
155
+ ```bash
156
+ git clone https://github.com/nodetool-ai/nodetool-mlx.git
157
+ cd nodetool-mlx
158
+ uv pip install -e .
159
+ uv pip install -r requirements-dev.txt
160
+ ```
161
+
162
+ If you prefer Poetry or pip, install the project the same way—just ensure dependencies are resolved against Python 3.11.
163
+
164
+ ## Managing Models
165
+
166
+ All MLX nodes rely on locally cached checkpoints. The recommended way to download and update them is through the **Models Manager** built into Nodetool:
167
+
168
+ 1. Open Nodetool → **Menu ▸ Models**
169
+ 2. Select the `mlx` tab to view the recommended checkpoints for each node
170
+ 3. Click **Download** for the models you plan to use; Nodetool stores them in the Hugging Face cache automatically
171
+ 4. The UI will keep track of model availability and prompt you when updates are available
172
+
173
+ Advanced users can still seed the Hugging Face cache manually, but using the UI integration ensures consistent paths and avoids missing-model errors in workflows.
174
+
175
+ ## Usage
176
+
177
+ 1. Install `nodetool-core` and this package in the same environment
178
+ 2. Run `nodetool-pkg scan --write --enrich` to generate package metadata
179
+ 3. Build workflows in the Nodetool UI using the `mlx` nodes
180
+
181
+ ## Development
182
+
183
+ Run tests and lint checks before submitting PRs:
184
+
185
+ ```bash
186
+ pytest -q
187
+ ruff check .
188
+ black --check .
189
+ ```
190
+
191
+ Most of the suite is written to run on any platform: the MLX runtimes are
192
+ imported lazily and the node logic is exercised against mocks. The handful of
193
+ tests that need `mflux` or `mlx-audio` skip themselves when those Apple Silicon
194
+ packages are unavailable, so a Linux run reports skips rather than failures.
195
+
196
+ If you change a node's `get_recommended_models()`, regenerate the committed
197
+ package metadata:
198
+
199
+ ```bash
200
+ nodetool-pkg scan --write --enrich
201
+ ```
202
+
203
+ `tests/test_package_metadata.py` fails when the two drift apart — the Nodetool
204
+ UI reads that file to populate the model picker, so a stale entry becomes a
205
+ model users cannot select or a download offer for a repository that no longer
206
+ exists.
207
+
208
+ ### Continuous integration
209
+
210
+ `.github/workflows/ci.yml` runs on every pull request:
211
+
212
+ | Job | Runner | What it covers |
213
+ | --- | --- | --- |
214
+ | Lint and format | ubuntu | `ruff check .` and `black --check .` |
215
+ | Test (linux) | ubuntu, Python 3.11 + 3.12 | the platform-independent suite, installed with `--no-deps` |
216
+ | Test (macOS) | macos-14 (Apple Silicon) | the full suite against the real MLX stack |
217
+ | Build wheel | ubuntu | `python -m build` plus `twine check` |
218
+
219
+ Please open issues or pull requests for bug fixes, new MLX models, or performance improvements. Contributions are welcome!