Compare commits

..
3 Commits
Author SHA1 Message Date
mlpy0 21a54c5ea0 docs: request the mlx extra in the documented setup commands (#2245)
Since #2087 moved mlx, mlx-lm, mlx-vlm and mflux out of `dependencies`
into the `mlx` extra, the documented setup path never installs them, and
`[tool.uv]` sets no default extras. `uv run exo` starts the API, then
every runner crashes with `ModuleNotFoundError: No module named 'mlx'`
(#2156).

Adds the extra to the commands documented as the way to set up:

- README macOS: `uv sync --extra mlx`
- README Linux: `uv sync --extra mlx-cpu`, with the mlx-cuda12 /
mlx-cuda13 alternatives
- CONTRIBUTING.md quick start
- `just sync` / `just sync-clean`, which `just build-app` runs before
pyinstaller — the spec aborts when the mlx Metal libraries are missing

Docs plus two justfile recipes; no dependency or lock changes. Backend
choice stays explicit, since mlx-cpu / mlx-cuda12 / mlx-cuda13 /
mlx-none are declared as conflicting extras.

#2234 overlaps on the macOS README block only, via a setup script that
runs `uv sync --extra mlx`; the Linux block, CONTRIBUTING.md and the
justfile are not covered there.
2026-08-25 18:59:53 +00:00
b5375f8cee Add Kimi K2.7-Code model card (official INT4 weights + vision) (#2167)
Adds a model card for
[moonshotai/Kimi-K2.7-Code](https://huggingface.co/moonshotai/Kimi-K2.7-Code),
released 2026-06-12.

Same architecture as Kimi K2.6 (`kimi_k25`, 61 layers, official INT4),
so the card mirrors the existing `moonshotai--Kimi-K2.6.toml`. Sampling
defaults per the model card (temperature 1.0 / top_p 0.95 for thinking
mode).

**Vision:** the official repo ships MoonViT weights inline, so I
extracted the 335 `vision_tower.*` / `mm_projector.*` tensors
(unmodified bf16) into
[aidiffuser/Kimi-K2.7-Code-vision](https://huggingface.co/aidiffuser/Kimi-K2.7-Code-vision),
following the `exolabs/Kimi-K2.6-vision` format. The vision config is
byte-identical to K2.6's; the extraction script is included in the repo
for verification. Happy to have this re-hosted under the exolabs org if
you prefer — it's a one-line change to the card.

**Tested:** distributed serving on 2× Mac Studio M3 Ultra (512 GB),
tensor parallelism, text + thinking + image understanding all confirmed
working.

Co-authored-by: aidiffuser <your-noreply-email@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-06-22 13:38:54 +00:00
OrbisAI Security cdf1add867 fix: upgrade devalue to 5.6.2 (CVE-2026-22774) (#2150)
## Summary
Upgrade devalue from 5.5.0 to 5.6.2 to fix CVE-2026-22774.

## Vulnerability
| Field | Value |
|-------|-------|
| **ID** | CVE-2026-22774 |
| **Severity** | HIGH |
| **Scanner** | trivy |
| **Rule** | `CVE-2026-22774` |
| **File** | `dashboard/package-lock.json` |
| **Assessment** | Likely exploitable |

**Description**: devalue: devalue: Denial of Service due to excessive
resource consumption from untrusted input

## Evidence

**Scanner confirmation**: trivy rule `CVE-2026-22774` flagged this
pattern.

**Production code**: This file is in the production codebase, not
test-only code.

## Threat Model Context

This is a web service - vulnerabilities in request handlers are directly
exploitable by remote attackers.

## Changes
- `dashboard/package.json`
- `dashboard/package-lock.json`

## Verification
- [x] Build passes
- [x] Scanner re-scan confirms fix
- [x] LLM code review passed

---
*This change addresses a pattern flagged by static analysis. The code
path handles user-influenced input and the fix reduces the attack
surface against both manual and automated exploitation.*

---
*Automated security fix by [OrbisAI Security](https://orbisappsec.com)*
2026-06-22 13:29:15 +00:00
9 changed files with 70 additions and 70 deletions

No files matched your search

-1
View File
@@ -6,7 +6,6 @@ digest.txt
# nix
.direnv/
.nix-devel/
# IDEA (PyCharm)
.idea
+1
View File
@@ -29,6 +29,7 @@ To run EXO from source:
git clone https://github.com/exo-explore/exo.git
cd exo/dashboard
npm install && npm run build && cd ..
uv sync --extra mlx
uv run exo
```
+9 -2
View File
@@ -118,7 +118,7 @@ Then restart the Nix daemon: `sudo launchctl kickstart -k system/org.nixos.nix-d
--force
```
Clone the repo, build the dashboard, and run exo:
Clone the repo, build the dashboard, install the dependencies, and run exo:
```bash
# Clone exo
@@ -127,6 +127,9 @@ git clone https://github.com/exo-explore/exo
# Build dashboard
cd exo/dashboard && npm install && npm run build && cd ..
# Install Python dependencies, including the MLX backend
uv sync --extra mlx
# Run exo
uv run exo
```
@@ -176,7 +179,7 @@ rustup toolchain install nightly
**Note:** The `macmon` package is macOS-only and not required for Linux.
Clone the repo, build the dashboard, and run exo:
Clone the repo, build the dashboard, install the dependencies, and run exo:
```bash
# Clone exo
@@ -185,6 +188,10 @@ git clone https://github.com/exo-explore/exo
# Build dashboard
cd exo/dashboard && npm install && npm run build && cd ..
# Install Python dependencies with the MLX backend for your hardware
# (NVIDIA: --extra mlx-cuda13 or --extra mlx-cuda12)
uv sync --extra mlx-cpu
# Run exo
uv run exo
```
+4 -3
View File
@@ -8,6 +8,7 @@
"name": "exo-dashboard",
"version": "1.0.0",
"dependencies": {
"devalue": "^5.6.2",
"highlight.js": "^11.11.1",
"katex": "^0.16.27",
"marked": "^17.0.1",
@@ -2331,9 +2332,9 @@
}
},
"node_modules/devalue": {
"version": "5.5.0",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.5.0.tgz",
"integrity": "sha512-69sM5yrHfFLJt0AZ9QqZXGCPfJ7fQjvpln3Rq5+PS03LD32Ost1Q9N+eEnaQwGRIriKkMImXD56ocjQmfjbV3w==",
"version": "5.6.2",
"resolved": "https://registry.npmjs.org/devalue/-/devalue-5.6.2.tgz",
"integrity": "sha512-nPRkjWzzDQlsejL1WVifk5rvcFi/y1onBRxjaFMjZeR9mFpqu2gmAZ9xUB9/IEanEP/vBtGeGganC/GO1fmufg==",
"license": "MIT"
},
"node_modules/enhanced-resolve": {
+3 -2
View File
@@ -11,8 +11,6 @@
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json"
},
"devDependencies": {
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",
"@sveltejs/adapter-static": "^3.0.10",
"@sveltejs/kit": "^2.48.4",
"@sveltejs/vite-plugin-svelte": "^5.0.0",
@@ -20,6 +18,8 @@
"@types/d3": "^7.4.3",
"@types/node": "^22",
"d3": "^7.9.0",
"prettier": "^3.4.2",
"prettier-plugin-svelte": "^3.3.3",
"svelte": "^5.0.0",
"svelte-check": "^4.0.0",
"tailwindcss": "^4.0.0",
@@ -28,6 +28,7 @@
"vite": "^6.0.0"
},
"dependencies": {
"devalue": "^5.6.2",
"highlight.js": "^11.11.1",
"katex": "^0.16.27",
"marked": "^17.0.1",
+1 -1
View File
@@ -146,7 +146,7 @@
config.treefmt.build.wrapper
# PYTHON
self'.packages.exo-devel.passthru.localRustEvenv
self'.packages.exo.passthru.evenv
uv
# RUST
+3 -18
View File
@@ -16,29 +16,14 @@ check:
uv run basedpyright --project pyproject.toml
sync:
uv sync --all-packages
uv sync --all-packages --extra mlx
sync-clean:
uv sync --all-packages --force-reinstall --no-cache
uv sync --all-packages --extra mlx --force-reinstall --no-cache
rust-rebuild:
#!/usr/bin/env bash
export UV_NO_SYNC=1
# build stubs
PYO3_PYTHON="$(uv run python -c 'import sys; print(sys.executable)')" cargo run --bin stub_gen
# install with maturin -> incremental builds
cd rust/exo_rs
maturin develop --uv
cd ../..
# symlink exo_rs to .nix-devel site packages
dst=".nix-devel/site-packages"
src="$(uv run python -c 'import sysconfig; print(sysconfig.get_path("purelib"))')"
mkdir -p "$dst"
rm -rf "$dst/exo_rs" "$dst"/exo_rs-*.dist-info
ln -s "$src/exo_rs" "$dst/exo_rs"
for dist_info in "$src"/exo_rs-*.dist-info; do
ln -s "$dist_info" "$dst/$(basename "$dist_info")"
done
uv sync --reinstall-package exo_rs
build-dashboard:
#!/usr/bin/env bash
+13 -43
View File
@@ -190,16 +190,6 @@ let
root = "$REPO_ROOT";
members = [ "exo" "exo-bench" ];
};
localRustOverlay = _final: prev: {
# The local Rust dev loop supplies exo_rs via PYTHONPATH after
# maturin develop. Keep it out of the Nix venv dependency graph
# so Rust edits do not trigger the Crane-built wheel.
exo = prev.exo.overrideAttrs (old: {
passthru = (old.passthru or { }) // {
dependencies = builtins.removeAttrs (old.passthru.dependencies or { }) [ "exo-rs" ];
};
});
};
pythonSet = (pkgs.callPackage inputs.pyproject-nix.build.packages {
inherit python;
}).overrideScope (
@@ -211,28 +201,16 @@ let
]
);
# mlx and mlx-cuda ship clashing cmake files - we dont need them at runtime anyway
venvSkip = [
"lib/python${python.pythonVersion}/site-packages/mlx/share/cmake/*"
"lib/python${python.pythonVersion}/site-packages/build_backend.py"
];
venv = name: (pythonSet.mkVirtualEnv "${name}-venv" members).overrideAttrs (_: { inherit venvSkip; });
evenv = name: ((pythonSet.overrideScope editableOverlay).mkVirtualEnv "${name}-evenv" (members // { exo = (members.exo or [ ]) ++ [ "dev" ]; exo-rs = [ ]; })).overrideAttrs (_: { inherit venvSkip; });
localRustEvenv = name: ((pythonSet.overrideScope (lib.composeExtensions editableOverlay localRustOverlay)).mkVirtualEnv "${name}-local-rust-evenv" (members // { exo = (members.exo or [ ]) ++ [ "dev" ]; })).overrideAttrs (_: { inherit venvSkip; });
venv = name: (pythonSet.mkVirtualEnv "${name}-venv" members).overrideAttrs (_: { venvSkip = [ "lib/python${python.pythonVersion}/site-packages/mlx/share/cmake/*" "lib/python${python.pythonVersion}/site-packages/build_backend.py" ]; });
mkApp =
let
libPath = lib.makeLibraryPath (
[ pkgs.stdenv.cc.cc.lib ] ++ lib.optionals cudaSupport [ cudaRoot ]
);
in
{ name
, text
, runtimeVenvFor ? venv
, setup ? ""
}:
pkgs.writeShellApplication {
text: name: pkgs.writeShellApplication {
inherit name;
text = ''
${setup}
LD_LIBRARY_PATH="${libPath}''${LD_LIBRARY_PATH:+:}''${LD_LIBRARY_PATH:-}" exec \
${lib.optionalString cudaSupport "nixglhost "} ${text}
'';
@@ -241,13 +219,14 @@ let
EXO_RESOURCES_DIR = inputs.self + /resources;
};
runtimeInputs = [
(runtimeVenvFor name)
(venv name)
] ++ lib.optionals cudaSupport [ pkgs.nix-gl-host ]
++ lib.optionals isDarwin [ pkgs.macmon ];
passthru = {
venv = venv name;
evenv = evenv name;
localRustEvenv = localRustEvenv name;
evenv = ((pythonSet.overrideScope editableOverlay).mkVirtualEnv "${name}-evenv" (members // { exo = (members.exo or [ ]) ++ [ "dev" ]; exo-rs = [ ]; })).overrideAttrs (_: {
venvSkip = [ "lib/python${python.pythonVersion}/site-packages/mlx/share/cmake/*" "lib/python${python.pythonVersion}/site-packages/build_backend.py" ];
});
} // lib.optionalAttrs cudaSupport {
inherit cudaRoot;
};
@@ -256,17 +235,8 @@ let
in
{
inherit venv;
mkPythonScript = { name, path }: mkApp { inherit name; text = ''python ${path} "$@"''; };
exo = mkApp { name = "exo"; text = ''exo "$@"''; };
exo-devel = mkApp {
name = "exo-devel";
runtimeVenvFor = localRustEvenv;
setup = ''
export REPO_ROOT="''${REPO_ROOT:-$PWD}"
export PYTHONPATH="$REPO_ROOT/.nix-devel/site-packages''${PYTHONPATH:+:$PYTHONPATH}"
'';
text = ''exo "$@"'';
};
mkPythonScript = path: mkApp ''python ${path} "$@"'';
exo = mkApp ''exo "$@"'' "exo";
};
in
{
@@ -274,7 +244,7 @@ in
{ self', pkgs, unfreePkgs, lib, ... }:
let
inherit (pkgs.stdenv.hostPlatform) isLinux;
inherit (mkPythonSet { inherit self' pkgs lib; members = { exo = [ "mlx-cpu" ]; }; }) exo exo-devel;
inherit (mkPythonSet { inherit self' pkgs lib; members = { exo = [ "mlx-cpu" ]; }; }) exo;
# Virtual environment with dev dependencies for testing
testVenv = (mkPythonSet {
@@ -302,12 +272,12 @@ in
in
{
packages = {
inherit exo exo-devel;
inherit exo;
# for running tests in ci
exo-test-env = testVenv;
exo-bench = mkBenchScript { name = "exo-bench"; path = inputs.self + /bench/exo_bench.py; };
exo-eval = mkBenchScript { name = "exo-eval"; path = inputs.self + /bench/exo_eval.py; };
exo-eval-tool-calls = mkBenchScript { name = "exo-eval-tool-calls"; path = inputs.self + /bench/eval_tool_calls.py; };
exo-bench = mkBenchScript "exo-bench" (inputs.self + /bench/exo_bench.py);
exo-eval = mkBenchScript "exo-eval" (inputs.self + /bench/exo_eval.py);
exo-eval-tool-calls = mkBenchScript "exo-eval-tool-calls" (inputs.self + /bench/eval_tool_calls.py);
# used by ./tests/run_exo_on.sh
exo-get-all-models-on-cluster = mkSimplePythonScript "exo-get-all-models-on-cluster" (inputs.self + /tests/get_all_models_on_cluster.py);
} // lib.optionalAttrs isLinux {
@@ -0,0 +1,36 @@
model_id = "moonshotai/Kimi-K2.7-Code"
n_layers = 61
hidden_size = 7168
num_key_value_heads = 64
supports_tensor = true
tasks = ["TextGeneration"]
family = "kimi"
quantization = ""
base_model = "Kimi K2.7 Code"
capabilities = ["text", "thinking", "thinking_toggle", "vision"]
context_length = 262144
backends = ["MlxMetal", "MlxCuda", "MlxCpu"]
[storage_size]
in_bytes = 595204986173
# Vision tower + mm_projector extracted unmodified (bf16) from the official
# repo, in the same format as exolabs/Kimi-K2.6-vision; extraction script
# included in the weights repo. Vision config is identical to Kimi-K2.6's.
[vision]
image_token_id = 163605
model_type = "kimi_vl"
weights_repo = "aidiffuser/Kimi-K2.7-Code-vision"
processor_repo = "moonshotai/Kimi-K2.7-Code"
# Source: https://huggingface.co/moonshotai/Kimi-K2.7-Code
# (recommends temperature 1.0 / top_p 0.95 for thinking mode, same as K2.6)
[sampling_defaults]
temperature = 1.0
top_p = 0.95
min_p = 0.01
[sampling_defaults.non_thinking]
temperature = 0.6
top_p = 0.95
min_p = 0.01