diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 029c1a3..630fcc8 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -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
@@ -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
@@ -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
@@ -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
diff --git a/MLXSharp.sln b/MLXSharp.sln
deleted file mode 100644
index 11abacc..0000000
--- a/MLXSharp.sln
+++ /dev/null
@@ -1,84 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio Version 17
-VisualStudioVersion = 17.0.31903.59
-MinimumVisualStudioVersion = 10.0.40219.1
-Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{827E0CD3-B72D-47B6-A68D-7590B98EB39B}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLXSharp", "src\MLXSharp\MLXSharp.csproj", "{69BB544C-9ADD-4561-8B9D-7ACED3B46296}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLXSharp.Tests", "src\MLXSharp.Tests\MLXSharp.Tests.csproj", "{8F2FA235-E636-4D11-A55D-450505BB8F19}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLXSharp.Native", "src\MLXSharp.Native\MLXSharp.Native.csproj", "{F5B45C67-1810-4A04-862F-C33A7DFAE4C2}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MLXSharp.SemanticKernel", "src\MLXSharp.SemanticKernel\MLXSharp.SemanticKernel.csproj", "{BF201BBA-D607-4EF5-BF9B-766D89B43A4A}"
-EndProject
-Global
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Any CPU = Debug|Any CPU
- Debug|x64 = Debug|x64
- Debug|x86 = Debug|x86
- Release|Any CPU = Release|Any CPU
- Release|x64 = Release|x64
- Release|x86 = Release|x86
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Debug|x64.ActiveCfg = Debug|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Debug|x64.Build.0 = Debug|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Debug|x86.ActiveCfg = Debug|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Debug|x86.Build.0 = Debug|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Release|Any CPU.Build.0 = Release|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Release|x64.ActiveCfg = Release|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Release|x64.Build.0 = Release|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Release|x86.ActiveCfg = Release|Any CPU
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296}.Release|x86.Build.0 = Release|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Debug|x64.ActiveCfg = Debug|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Debug|x64.Build.0 = Debug|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Debug|x86.ActiveCfg = Debug|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Debug|x86.Build.0 = Debug|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Release|Any CPU.Build.0 = Release|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Release|x64.ActiveCfg = Release|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Release|x64.Build.0 = Release|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Release|x86.ActiveCfg = Release|Any CPU
- {8F2FA235-E636-4D11-A55D-450505BB8F19}.Release|x86.Build.0 = Release|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Debug|x64.ActiveCfg = Debug|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Debug|x64.Build.0 = Debug|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Debug|x86.ActiveCfg = Debug|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Debug|x86.Build.0 = Debug|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Release|Any CPU.Build.0 = Release|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Release|x64.ActiveCfg = Release|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Release|x64.Build.0 = Release|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Release|x86.ActiveCfg = Release|Any CPU
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2}.Release|x86.Build.0 = Release|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Debug|x64.ActiveCfg = Debug|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Debug|x64.Build.0 = Debug|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Debug|x86.ActiveCfg = Debug|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Debug|x86.Build.0 = Debug|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Release|Any CPU.Build.0 = Release|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Release|x64.ActiveCfg = Release|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Release|x64.Build.0 = Release|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Release|x86.ActiveCfg = Release|Any CPU
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A}.Release|x86.Build.0 = Release|Any CPU
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
- GlobalSection(NestedProjects) = preSolution
- {69BB544C-9ADD-4561-8B9D-7ACED3B46296} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
- {8F2FA235-E636-4D11-A55D-450505BB8F19} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
- {F5B45C67-1810-4A04-862F-C33A7DFAE4C2} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
- {BF201BBA-D607-4EF5-BF9B-766D89B43A4A} = {827E0CD3-B72D-47B6-A68D-7590B98EB39B}
- EndGlobalSection
-EndGlobal
diff --git a/MLXSharp.slnx b/MLXSharp.slnx
new file mode 100644
index 0000000..e72918c
--- /dev/null
+++ b/MLXSharp.slnx
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/README.md b/README.md
index 041bea6..9e0af8e 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,6 @@ The design mirrors the packaging approach from projects such as [LLamaSharp](htt
- `IChatClient`, `IEmbeddingGenerator`, 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.
@@ -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
```
@@ -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 [](https://www.nuget.org/packages/MLXSharp.SemanticKernel)
Semantic Kernel integration:
@@ -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:
diff --git a/TESTING.md b/TESTING.md
index 2aa064c..e3081eb 100644
--- a/TESTING.md
+++ b/TESTING.md
@@ -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 але повертає тестові дані замість реальних результатів моделі.
diff --git a/src/MLXSharp.Native/MLXSharp.Native.csproj b/src/MLXSharp.Native/MLXSharp.Native.csproj
deleted file mode 100644
index 911324e..0000000
--- a/src/MLXSharp.Native/MLXSharp.Native.csproj
+++ /dev/null
@@ -1,15 +0,0 @@
-
-
- true
- false
- true
-
-
-
-
-
-
diff --git a/src/MLXSharp.Native/README.md b/src/MLXSharp.Native/README.md
deleted file mode 100644
index 195db0a..0000000
--- a/src/MLXSharp.Native/README.md
+++ /dev/null
@@ -1,7 +0,0 @@
-# MLXSharp.Native
-
-This package mirrors the layout that MLXSharp expects when resolving native binaries.
-It ships the `libmlxsharp` stub that our managed layer uses during development and in automated tests.
-The Linux stub lives as a Base64-encoded payload (`libmlxsharp.so.b64`) so we can keep Git history free of binary blobs.
-`MlxNativeLibrary` expands the encoded payload to `libmlxsharp.so` automatically the first time the native backend loads.
-Drop the macOS build of the wrapper into `runtimes/osx-arm64/native/` before publishing a release build.
diff --git a/src/MLXSharp/MLXSharp.csproj b/src/MLXSharp/MLXSharp.csproj
index 993772e..3a7caf4 100644
--- a/src/MLXSharp/MLXSharp.csproj
+++ b/src/MLXSharp/MLXSharp.csproj
@@ -7,16 +7,9 @@
-
-
-
-
- $(MSBuildProjectDirectory)..\..\native\build\libmlxsharp.dylib
- ..\MLXSharp.Native\runtimes\osx-arm64\native\libmlxsharp.dylib
+ $([System.IO.Path]::Combine('$(MSBuildProjectDirectory)','..','..','native','build','libmlxsharp.dylib'))
+ $([System.IO.Path]::Combine('$(MSBuildProjectDirectory)','runtimes','osx-arm64','native','libmlxsharp.dylib'))
false
@@ -37,9 +30,9 @@
Text="libmlxsharp.dylib is missing. Build the native library or supply MLXSharpMacNativeBinary before packing." />
-
+
-