Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 34 additions & 14 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ jobs:
run: dotnet --info

- name: Restore dependencies
run: dotnet restore MLXSharp.sln
run: dotnet restore

- name: Build C# projects (initial validation)
run: dotnet build MLXSharp.sln --configuration Release --no-restore
run: dotnet build --configuration Release --no-restore

- name: Install CMake
run: brew install cmake
Expand All @@ -41,7 +41,7 @@ jobs:
ls -la src/MLXSharp.Native/runtimes/osx-arm64/native/

- name: Rebuild solution with native libraries
run: dotnet build MLXSharp.sln --configuration Release --no-restore
run: dotnet build --configuration Release --no-restore

- name: Setup Python for HuggingFace
uses: actions/setup-python@v5
Expand All @@ -66,7 +66,7 @@ jobs:
ls -la "$TEST_OUTPUT/runtimes/osx-arm64/native/"

- name: Run tests
run: dotnet test MLXSharp.sln --configuration Release --no-build --logger "trx;LogFileName=TestResults.trx" --results-directory artifacts/test-results
run: dotnet test --configuration Release --no-build --logger "trx;LogFileName=TestResults.trx" --results-directory artifacts/test-results
env:
MLXSHARP_MODEL_PATH: ${{ github.workspace }}/models/Qwen1.5-0.5B-Chat-4bit

Expand All @@ -78,22 +78,42 @@ jobs:
cp src/MLXSharp.Native/runtimes/osx-arm64/native/libmlxsharp.dylib artifacts/native/

- name: Pack MLXSharp library
run: dotnet pack src/MLXSharp/MLXSharp.csproj --configuration Release --output artifacts/packages \
-p:MLXSharpMacNativeBinary=$GITHUB_WORKSPACE/native/build/libmlxsharp.dylib
run: dotnet pack src/MLXSharp/MLXSharp.csproj --configuration Release --output artifacts/packages -p:MLXSharpMacNativeBinary=$GITHUB_WORKSPACE/native/build/libmlxsharp.dylib

- name: Pack MLXSharp.SemanticKernel library
run: dotnet pack src/MLXSharp.SemanticKernel/MLXSharp.SemanticKernel.csproj --configuration Release --output artifacts/packages \
-p:MLXSharpMacNativeBinary=$GITHUB_WORKSPACE/native/build/libmlxsharp.dylib
run: dotnet pack src/MLXSharp.SemanticKernel/MLXSharp.SemanticKernel.csproj --configuration Release --output artifacts/packages -p:MLXSharpMacNativeBinary=$GITHUB_WORKSPACE/native/build/libmlxsharp.dylib

- name: Verify package contains native libraries
run: |
echo "Checking package contents..."
if unzip -l artifacts/packages/*.nupkg | grep -q "runtimes/osx-arm64/native/libmlxsharp.dylib"; then
echo "✓ Native library found in package"
else
echo "✗ ERROR: Native library NOT found in package!"
echo "Package contents:"
unzip -l artifacts/packages/*.nupkg
shopt -s nullglob
packages=(artifacts/packages/*.nupkg)
if [ ${#packages[@]} -eq 0 ]; then
echo "✗ ERROR: No packages were produced"
exit 1
fi

missing=0
for package in "${packages[@]}"; do
echo "Inspecting ${package}"
filename=$(basename "${package}")
case "${filename}" in
MLXSharp.*.nupkg)
if unzip -l "${package}" | grep -q "runtimes/osx-arm64/native/libmlxsharp.dylib"; then
echo " ✓ Native library found"
else
echo " ✗ Native library NOT found"
unzip -l "${package}"
missing=1
fi
;;
*)
echo " ↷ Skipping native check for ${filename}"
;;
esac
done

if [ $missing -ne 0 ]; then
exit 1
fi

Expand Down
84 changes: 0 additions & 84 deletions MLXSharp.sln

This file was deleted.

12 changes: 12 additions & 0 deletions MLXSharp.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Solution>
<Configurations>
<Platform Name="Any CPU" />
<Platform Name="x64" />
<Platform Name="x86" />
</Configurations>
<Folder Name="/src/">
<Project Path="src/MLXSharp.SemanticKernel/MLXSharp.SemanticKernel.csproj" />
<Project Path="src/MLXSharp.Tests/MLXSharp.Tests.csproj" />
<Project Path="src/MLXSharp/MLXSharp.csproj" />
</Folder>
</Solution>
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ The design mirrors the packaging approach from projects such as [LLamaSharp](htt
- `IChatClient`, `IEmbeddingGenerator<string, Embedding<float)>`, and image generation helpers that adhere to the `Microsoft.Extensions.AI` abstractions.
- Builder-based backend configuration with a deterministic managed implementation for tests and a P/Invoke powered native backend.
- Native library resolver that probes application directories, `MLXSHARP_LIBRARY`, or packaged runtimes and loads `libmlxsharp` on demand.
- `MLXSharp.Native` packaging project that ships stub binaries for CI (Linux x64 today) and a placeholder `osx-arm64` folder for the production MLX wrapper.
- Dependency injection extensions (`AddMlx`) in **MLXSharp** package.
- Semantic Kernel integration (`AddMlxChatCompletion`) in separate **MLXSharp.SemanticKernel** package.
- Integration test suite that exercises chat, embedding, image, and Semantic Kernel flows against both managed and native backends.
Expand All @@ -18,9 +17,8 @@ The design mirrors the packaging approach from projects such as [LLamaSharp](htt
```
├── extern/mlx # Git submodule with the official MLX sources
├── native/ # Native wrapper scaffold (CMake project)
├── src/MLXSharp/ # Managed library with Microsoft.Extensions.AI adapters
├── src/MLXSharp/ # Managed library with Microsoft.Extensions.AI adapters + packaged runtimes
├── src/MLXSharp.SemanticKernel/ # Semantic Kernel integration (separate package)
├── src/MLXSharp.Native/ # NuGet-ready container for native binaries
└── src/MLXSharp.Tests/ # Integration tests covering DI and Semantic Kernel
```

Expand Down Expand Up @@ -81,10 +79,12 @@ dotnet add package MLXSharp

This package contains:
- Managed DLL with `Microsoft.Extensions.AI` implementations
- Native libraries in `runtimes/{rid}/native/`:
- `runtimes/linux-x64/native/libmlxsharp.so` - stub for CI/testing
- Native assets in `runtimes/{rid}/native/`:
- `runtimes/linux-x64/native/libmlxsharp.so.b64` - Base64-encoded stub that `MlxNativeLibrary` expands for CI/testing
- `runtimes/osx-arm64/native/libmlxsharp.dylib` - built in CI on macOS

`MlxNativeLibrary` materialises `libmlxsharp.so` from the encoded payload on first use so Git history stays free of binary blobs while tests retain deterministic behaviour.

### MLXSharp.SemanticKernel [![NuGet](https://img.shields.io/nuget/v/MLXSharp.SemanticKernel.svg)](https://www.nuget.org/packages/MLXSharp.SemanticKernel)

Semantic Kernel integration:
Expand All @@ -99,7 +99,7 @@ This package depends on MLXSharp and adds Semantic Kernel chat completion servic

GitHub Actions automatically:
1. Compiles native wrapper with MLX submodule
2. Copies `libmlxsharp.dylib` to `src/MLXSharp.Native/runtimes/osx-arm64/native/`
2. Copies `libmlxsharp.dylib` to `src/MLXSharp/runtimes/osx-arm64/native/`
3. Packs managed + native together in NuGet package

At runtime `MlxNativeLibrary` automatically finds the right library:
Expand Down
2 changes: 1 addition & 1 deletion TESTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ dotnet test
brew install cmake
cmake -S native -B native/build -DCMAKE_BUILD_TYPE=Release
cmake --build native/build --target mlxsharp
cp native/build/libmlxsharp.dylib src/MLXSharp.Native/runtimes/osx-arm64/native/
cp native/build/libmlxsharp.dylib src/MLXSharp/runtimes/osx-arm64/native/
```

Stub версія лінкується з MLX але повертає тестові дані замість реальних результатів моделі.
Expand Down
15 changes: 0 additions & 15 deletions src/MLXSharp.Native/MLXSharp.Native.csproj

This file was deleted.

7 changes: 0 additions & 7 deletions src/MLXSharp.Native/README.md

This file was deleted.

15 changes: 4 additions & 11 deletions src/MLXSharp/MLXSharp.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,9 @@
<PackageReference Include="Microsoft.Extensions.AI" Version="9.9.1" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\MLXSharp.Native\MLXSharp.Native.csproj"
ReferenceOutputAssembly="false"
PrivateAssets="all"
IncludeAssets="none" />
</ItemGroup>

<PropertyGroup>
<MLXSharpMacNativeBinary Condition="'$(MLXSharpMacNativeBinary)' == ''">$(MSBuildProjectDirectory)..\..\native\build\libmlxsharp.dylib</MLXSharpMacNativeBinary>
<MLXSharpMacNativeDestination>..\MLXSharp.Native\runtimes\osx-arm64\native\libmlxsharp.dylib</MLXSharpMacNativeDestination>
<MLXSharpMacNativeBinary Condition="'$(MLXSharpMacNativeBinary)' == ''">$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)','..','..','native','build','libmlxsharp.dylib'))</MLXSharpMacNativeBinary>
<MLXSharpMacNativeDestination>$([System.IO.Path]::Combine('$(MSBuildProjectDirectory)','runtimes','osx-arm64','native','libmlxsharp.dylib'))</MLXSharpMacNativeDestination>
<MLXSharpSkipMacNativeValidation Condition="'$(MLXSharpSkipMacNativeValidation)' == ''">false</MLXSharpSkipMacNativeValidation>
</PropertyGroup>

Expand All @@ -37,9 +30,9 @@
Text="libmlxsharp.dylib is missing. Build the native library or supply MLXSharpMacNativeBinary before packing." />
</Target>

<!-- Include native binaries from MLXSharp.Native project into this package -->
<!-- Include native binaries embedded in this project -->
<ItemGroup>
<None Include="..\MLXSharp.Native\runtimes\**\*.*"
<None Include="runtimes\**\*.*"
Pack="true"
PackagePath="runtimes/%(RecursiveDir)%(Filename)%(Extension)"
CopyToOutputDirectory="PreserveNewest"
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
Place the macOS arm64 build of libmlxsharp.dylib here before packing MLXSharp.Native for distribution.
Place the macOS arm64 build of libmlxsharp.dylib here before packing MLXSharp for distribution.
Loading