exo: 0.0.14-alpha -> 1.0.62 (#477442)

This commit is contained in:
kirillrdy
2026-01-18 20:14:42 +00:00
committed by GitHub
3 changed files with 213 additions and 46 deletions
@@ -0,0 +1,17 @@
diff --git a/src/exo/utils/dashboard_path.py b/src/exo/utils/dashboard_path.py
index b5ce9c04..ec60ef4a 100644
--- a/src/exo/utils/dashboard_path.py
+++ b/src/exo/utils/dashboard_path.py
@@ -5,11 +5,7 @@ from typing import cast
def find_dashboard() -> Path:
- dashboard = (
- _find_dashboard_in_env()
- or _find_dashboard_in_repo()
- or _find_dashboard_in_bundle()
- )
+ dashboard = "@dashboard@"
if not dashboard:
raise FileNotFoundError(
"Unable to locate dashboard assets - make sure the dashboard has been built, or export DASHBOARD_DIR if you've built the dashboard elsewhere."
@@ -0,0 +1,29 @@
diff --git a/src/exo/master/api.py b/src/exo/master/api.py
index 30f87e2a..4aac51fe 100644
--- a/src/exo/master/api.py
+++ b/src/exo/master/api.py
@@ -67,7 +67,14 @@ from exo.utils.channels import Receiver, Sender, channel
from exo.utils.dashboard_path import find_dashboard
from exo.utils.event_buffer import OrderedBuffer
-encoding = load_harmony_encoding(HarmonyEncodingName.HARMONY_GPT_OSS)
+_encoding: object = None
+
+
+def get_encoding():
+ global _encoding
+ if _encoding is None:
+ _encoding = load_harmony_encoding(HarmonyEncodingName.HARMONY_GPT_OSS)
+ return _encoding
def chunk_to_response(
@@ -382,7 +389,7 @@ class API:
)
async def _process_gpt_oss(self, token_chunks: Receiver[TokenChunk]):
- stream = StreamableParser(encoding, role=Role.ASSISTANT)
+ stream = StreamableParser(_encoding, role=Role.ASSISTANT)
thinking = False
async for chunk in token_chunks:
+167 -46
View File
@@ -3,80 +3,201 @@
stdenv,
fetchFromGitHub,
python3Packages,
gitUpdater,
}:
python3Packages.buildPythonApplication rec {
pname = "exo";
version = "0.0.14-alpha";
pyproject = true;
replaceVars,
macmon,
# pyo3-bindings
rustPlatform,
# dashboard
buildNpmPackage,
fetchNpmDeps,
writableTmpDirAsHomeHook,
nix-update-script,
}:
let
version = "1.0.63";
src = fetchFromGitHub {
name = "exo";
owner = "exo-explore";
repo = "exo";
tag = "v${version}";
hash = "sha256-GoYfpr6oFpreWQtSomOwgfzSoBAbjqGZ1mcc0u9TBl4=";
hash = "sha256-aQ3rGLtT/zvIVdKQcwqODulzEHBKg7KMkBg3KJEscho=";
};
build-system = with python3Packages; [ setuptools ];
pyo3-bindings = python3Packages.buildPythonPackage (finalAttrs: {
pname = "exo-pyo3-bindings";
inherit version src;
pyproject = true;
buildAndTestSubdir = "rust/exo_pyo3_bindings";
cargoDeps = rustPlatform.fetchCargoVendor {
inherit (finalAttrs) pname src version;
hash = "sha256-N7B1WFqPdqeNPZe9hXGyX7F3EbB1spzeKc19BFDDwls=";
};
# Bypass rust nightly features not being available on rust stable
env.RUSTC_BOOTSTRAP = 1;
nativeBuildInputs = [
rustPlatform.cargoSetupHook
rustPlatform.maturinBuildHook
];
nativeCheckInputs = with python3Packages; [
pytest-asyncio
pytestCheckHook
];
enabledTestPaths = [
"rust/exo_pyo3_bindings/tests/"
];
});
dashboard = buildNpmPackage (finalAttrs: {
pname = "exo-dashboard";
inherit src version;
sourceRoot = "${finalAttrs.src.name}/dashboard";
npmDeps = fetchNpmDeps {
inherit (finalAttrs)
pname
version
src
sourceRoot
;
fetcherVersion = 2;
hash = "sha256-w3FZL/yy8R+SWCQF7+v21sKyizvZMmipG6IfhJeSjyQ=";
};
});
in
python3Packages.buildPythonApplication (finalAttrs: {
pname = "exo";
pyproject = true;
inherit version src;
patches = [
(replaceVars ./inject-dashboard-path.patch {
dashboard = "${dashboard}/lib/node_modules/${dashboard.pname}/build";
})
];
postPatch = ''
substituteInPlace pyproject.toml \
--replace-fail "uv_build>=0.8.9,<0.9.0" "uv_build"
''
# MemoryObjectStreamState was renamed in
# https://github.com/agronholm/anyio/pull/1009/changes/bdc945a826d0d5917aea3517ceb9fe335b468094
+ ''
substituteInPlace src/exo/utils/channels.py \
--replace-fail \
"MemoryObjectStreamState as AnyioState," \
"_MemoryObjectStreamState as AnyioState,"
''
+ lib.optionalString stdenv.hostPlatform.isDarwin ''
substituteInPlace src/exo/worker/utils/macmon.py \
--replace-fail \
'path = shutil.which("macmon")' \
'path = "${lib.getExe macmon}"'
substituteInPlace src/exo/worker/utils/tests/test_macmon.py \
--replace-fail \
'cmd=["macmon"' \
'cmd=["${lib.getExe macmon}"'
'';
build-system = with python3Packages; [
uv-build
];
pythonRelaxDeps = true;
pythonRemoveDeps = [ "uuid" ];
dependencies = with python3Packages; [
aiohttp
aiohttp-cors
aiofiles
grpcio
grpcio-tools
jinja2
numpy
nuitka
nvidia-ml-py
opencv-python
pillow
prometheus-client
protobuf
psutil
pydantic
requests
rich
scapy
tqdm
transformers
tinygrad
uvloop
pythonRemoveDeps = [
"types-aiofiles"
"uuid"
];
dependencies =
with python3Packages;
[
aiofiles
aiohttp
aiohttp-cors
anyio
fastapi
filelock
grpcio
grpcio-tools
httpx
huggingface-hub
hypercorn
jinja2
loguru
mlx
mlx-lm
nvidia-ml-py
openai
openai-harmony
opencv-python
pillow
prometheus-client
psutil
pydantic
pyo3-bindings
rustworkx
scapy
tiktoken
tinygrad
transformers
uvloop
]
++ sqlalchemy.optional-dependencies.asyncio;
pythonImportsCheck = [
"exo"
"exo.inference.tinygrad.models"
"exo.main"
];
nativeCheckInputs = with python3Packages; [
mlx
pytestCheckHook
nativeCheckInputs = [
python3Packages.pytest-asyncio
python3Packages.pytestCheckHook
writableTmpDirAsHomeHook
];
# Otherwise fails with 'import file mismatch'
preCheck = ''
rm src/exo/__init__.py
'';
disabledTests = lib.optionals stdenv.hostPlatform.isDarwin [
# AssertionError: assert "MacMon not found in PATH" in str(exc_info.value)
"test_macmon_not_found_raises_macmon_error"
# ValueError: zip() argument 2 is longer than argument 1
"test_events_processed_in_correct_order"
];
disabledTestPaths = [
"test/test_tokenizers.py"
# All tests hang indefinitely
"src/exo/worker/tests/unittests/test_mlx/test_tokenizers.py"
];
# Tests require `mlx` which is not supported on linux.
doCheck = stdenv.hostPlatform.isDarwin;
passthru = {
updateScript = gitUpdater {
rev-prefix = "v-";
};
updateScript = nix-update-script { };
exo-pyo3-bindings = pyo3-bindings;
exo-dashboard = dashboard;
};
meta = {
description = "Run your own AI cluster at home with everyday devices";
homepage = "https://github.com/exo-explore/exo";
changelog = "https://github.com/exo-explore/exo/releases/tag/v${version}";
changelog = "https://github.com/exo-explore/exo/releases/tag/${finalAttrs.src.tag}";
license = lib.licenses.gpl3Only;
maintainers = with lib.maintainers; [ GaetanLepage ];
mainProgram = "exo";
};
}
})