Tags: exo-explore/exo
Tags
Fix draft release detection (attempt 3) (#1176) ## Motivation Previous fix still failed in CI. Suspecting permissions issue with GITHUB_TOKEN not being able to see draft releases via API. ## Changes 1. Add explicit `permissions: contents: write` to the job 2. Use `gh release list` first to check if draft exists (this uses a different code path that might work better) 3. Add debug echo statements ## Test Plan Delete v1.0.63 tag and re-push after merging. Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
ci: compute CURRENT_PROJECT_VERSION from semver
Previous Sparkle builds were cut from a different repo with different
build numbers, breaking version ordering. Users aren't receiving updates
because CFBundleVersion values don't reflect the actual version sequence.
Added a step to compute the build version deterministically from semver:
PRERELEASE + (1000 * PATCH) + (1_000_000 * MINOR) + (1_000_000_000 * MAJOR).
Release versions use prerelease=999 to ensure they're always higher than
their prereleases (e.g., 1.0.61 > 1.0.61-alpha.3).
This ensures consistent version ordering across repos, allowing Sparkle
to correctly identify and deliver updates to users.
Test plan:
- Verified formula with test script:
```sh
compute_version() {
VERSION="$1"
BASE_VERSION="${VERSION%%-*}"
MAJOR=$(echo "$BASE_VERSION" | cut -d. -f1)
MINOR=$(echo "$BASE_VERSION" | cut -d. -f2)
PATCH=$(echo "$BASE_VERSION" | cut -d. -f3)
if [[ "$VERSION" == *-* ]]; then
PRERELEASE_PART="${VERSION#*-}"
PRERELEASE_NUM="${PRERELEASE_PART##*.}"
if ! [[ "$PRERELEASE_NUM" =~ ^[0-9]+$ ]]; then
PRERELEASE_NUM=0
fi
else
PRERELEASE_NUM=999
fi
BUILD_VERSION=$((PRERELEASE_NUM + 1000 * PATCH + 1000000 * MINOR + 1000000000 * MAJOR))
printf "%-20s -> %12s\n" "$VERSION" "$BUILD_VERSION"
}
compute_version "1.0.61-alpha.2"
compute_version "1.0.61-alpha.3"
compute_version "1.0.61"
compute_version "1.0.62-alpha.1"
compute_version "1.1.0-alpha.1"
compute_version "2.0.0-alpha.1"
compute_version "0.0.0-alpha.0"
compute_version "0.0.1-alpha.1"
compute_version "1.2.3"
compute_version "1.2.3-beta.5"
```
- Output:
```sh
Version -> Build Number
----------------------------------------
1.0.61-alpha.2 -> 1000061002
1.0.61-alpha.3 -> 1000061003
1.0.61 -> 1000061999
1.0.62-alpha.1 -> 1000062001
1.1.0-alpha.1 -> 1001000001
2.0.0-alpha.1 -> 2000000001
0.0.0-alpha.0 -> 0
0.0.1-alpha.1 -> 1001
1.2.3 -> 1002003999
1.2.3-beta.5 -> 1002003005
```
- Confirmed ordering: alpha.2 < alpha.3 < release < next-alpha
Use presigned URLs for bug report uploads (#1109) ## Motivation Previously we hardcoded AWS credentials into the app. This is not good practice. ## Changes Use presigned URLs instead. ## Why It Works Presigned URLs are an S3 feature for this kind of thing. They provide an expiring presigned URL with certain permissions. In this case we have a presigned URL with `s3:PutObject` permission that expires after 5 minutes. The client uses this presigned URL to upload a bug report instead of using its own credentials to sign a request. This also simplifies a lot of the Swift code. ## Test Plan ### Manual Testing On a single MacBook, I downloaded the app and sent a bug report. It worked and appeared in the bucket.
add a server for distributed testing in /tests until we work out a st… …able solution. (#1098) ## Motivation Testing multiple devices simultaneously requires coordination, and we don't necessarily want to run a full EXO to test single components. We need a mid-scale integration testing framework for distributed tests. ## Changes Add a simple python server + bash query that runs Jaccl and Ring tests without constructing a worker/master/networking. The query relies on all devices being accessible over tailscale, currently. ## Test Plan Manually tested RDMA + Ring inference on 2 nodes.
exo-bench (Benchmark model pp & tg speed) (#1099) ## Motivation This PR implements benchmarking in the style of llama-bench. The main difficulty here is the fact that exo is not a library - it exposes an endpoint. This means that benchmarking numbers will be inaccurate if the API is measured. The solution assumes nodes are set up with uv run exo (or via the app), and then hits the new endpoint /bench/chat/completions to retrieve generation statistics directly from mlx_lm. <!-- Why is this change needed? What problem does it solve? --> This will allow us to release benchmarks for models and perform regression tests. TODO: Performance benchmarking. <!-- If it fixes an open issue, please link to the issue here --> ## Changes <!-- Describe what you changed in detail --> - Adds /bench/chat/completions endpoint - Adds BenchChatCompletion/Response - Adds a logits processor to prevent response from ending early - Adds a "Prompt Sizer" which downloads the tokenizer and dynamically adjusts the prompt of "a" to fit the desired prompt size. - Reduce prefill step size to 2048 for now (in future, dynamically adjust this value) <!-- Explain why your approach solves the problem --> ## Test Plan ### Manual Testing <!-- Hardware: (e.g., MacBook Pro M1 Max 32GB, Mac Mini M2 16GB, connected via Thunderbolt 4) --> <!-- What you did: --> <!-- - --> Benchmarked Llama, Qwen, DeepSeek and Kimi models. Will require several fixes to run consistently on all configurations (to be done in the future). Manually tested the normal API to verify chat requests complete as expected. ### Automated Testing <!-- Describe changes to automated tests, or how existing tests cover this change --> <!-- - --> Not really possible. Type checker passes.
feat(macos-app): add custom namespace UI for cluster isolation Add Advanced Options section with custom namespace field that allows users to override EXO_LIBP2P_NAMESPACE environment variable. This enables splitting machines that can see each other into separate clusters. - Added customNamespace property with UserDefaults persistence - Added Advanced Options collapsible section with text field - Added Save & Restart button that auto-restarts exo process - Namespace replaces buildTag when custom value is set - Falls back to buildTag (version) when namespace is empty
PreviousNext