Skip to content
Open
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
26 changes: 8 additions & 18 deletions .pipelines/templates/build-core-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ steps:
inputs:
command: restore
projects: '$(nsRoot)/src/FoundryLocalCore/Core/Core.csproj'
restoreArguments: '-r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.26100.0 /p:UseWinML=true'
restoreArguments: '-r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.18362.0 /p:UseWinML=true'
feedsToUse: config
nugetConfigPath: '$(nsRoot)/nuget.config'

Expand All @@ -67,14 +67,14 @@ steps:
inputs:
command: build
projects: '$(nsRoot)/src/FoundryLocalCore/Core/Core.csproj'
arguments: '--no-restore -r ${{ parameters.flavor }} -f net9.0-windows10.0.26100.0 /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.26100.0 /p:UseWinML=true'
arguments: '--no-restore -r ${{ parameters.flavor }} -f net9.0-windows10.0.18362.0 /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.18362.0 /p:UseWinML=true'

- task: DotNetCoreCLI@2
displayName: 'Publish FLC AOT ${{ parameters.flavor }} (WinML)'
inputs:
command: publish
projects: '$(nsRoot)/src/FoundryLocalCore/Core/Core.csproj'
arguments: '--no-restore --no-build -r ${{ parameters.flavor }} -f net9.0-windows10.0.26100.0 /p:Platform=${{ parameters.platform }} /p:Configuration=Release /p:PublishAot=true /p:NetTargetFramework=net9.0-windows10.0.26100.0 /p:UseWinML=true'
arguments: '--no-restore --no-build -r ${{ parameters.flavor }} -f net9.0-windows10.0.18362.0 /p:Platform=${{ parameters.platform }} /p:Configuration=Release /p:PublishAot=true /p:NetTargetFramework=net9.0-windows10.0.18362.0 /p:UseWinML=true'
publishWebProjects: false
zipAfterPublish: false

Expand All @@ -84,7 +84,7 @@ steps:
inputs:
command: restore
projects: '$(nsRoot)/test/FoundryLocalCore/Core/FoundryLocalCore.Tests.csproj'
restoreArguments: '-r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.26100.0 /p:UseWinML=true'
restoreArguments: '-r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.18362.0 /p:UseWinML=true'
feedsToUse: config
nugetConfigPath: '$(nsRoot)/nuget.config'

Expand All @@ -93,7 +93,7 @@ steps:
inputs:
command: build
projects: '$(nsRoot)/test/FoundryLocalCore/Core/FoundryLocalCore.Tests.csproj'
arguments: '--no-restore -r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.26100.0 /p:UseWinML=true'
arguments: '--no-restore -r ${{ parameters.flavor }} /p:Platform=${{ parameters.platform }} /p:IncludeWebService=true /p:Configuration=Release /p:NetTargetFramework=net9.0-windows10.0.18362.0 /p:UseWinML=true'

- task: DotNetCoreCLI@2
displayName: 'Test FLC ${{ parameters.flavor }} (WinML)'
Expand Down Expand Up @@ -170,18 +170,8 @@ steps:
script: |
$destDir = "$(Build.ArtifactStagingDirectory)/native"
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
# WinML publishes additional files (e.g. WindowsAppRuntime Bootstrapper DLLs)
# beyond Microsoft.AI.Foundry.Local.Core.*.
$isWinML = "${{ parameters.isWinML }}" -eq "True"
if ($isWinML) {
Get-ChildItem "$(nsRoot)/artifacts/publish" -Recurse -File |
Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" -or $_.Name -eq "Microsoft.WindowsAppRuntime.Bootstrap.dll" } |
Copy-Item -Destination $destDir -Force
} else {
Get-ChildItem "$(nsRoot)/artifacts/publish" -Recurse -File |
Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" } |
Copy-Item -Destination $destDir -Force
}
Get-ChildItem "$(nsRoot)/artifacts/publish" -Recurse -File |
Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" } |
Copy-Item -Destination $destDir -Force
Write-Host "Staged binaries:"
Get-ChildItem $destDir | ForEach-Object { Write-Host " $($_.Name)" }

86 changes: 67 additions & 19 deletions .pipelines/templates/package-core-steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ steps:
'@
$platforms = $platformsJson | ConvertFrom-Json

$isWinML = "${{ parameters.isWinML }}" -eq "True"

foreach ($p in $platforms) {
$srcDir = "$(Pipeline.Workspace)/$($p.artifactName)"
Write-Host "Looking for artifacts at: $srcDir"
Expand All @@ -47,22 +49,63 @@ steps:
}
$destDir = "$unifiedPath/runtimes/$($p.name)/native"
New-Item -ItemType Directory -Path $destDir -Force | Out-Null
# WinML artifacts include WindowsAppRuntime Bootstrapper DLLs in addition
# to Microsoft.AI.Foundry.Local.Core.*.
$isWinML = "${{ parameters.isWinML }}" -eq "True"
if ($isWinML) {
Get-ChildItem $srcDir -File |
Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" -or $_.Name -eq "Microsoft.WindowsAppRuntime.Bootstrap.dll" } |
Copy-Item -Destination $destDir -Force
} else {
Get-ChildItem $srcDir -File | Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" } |
Copy-Item -Destination $destDir -Force
}
Get-ChildItem $srcDir -File | Where-Object { $_.Name -like "Microsoft.AI.Foundry.Local.Core.*" } |
Copy-Item -Destination $destDir -Force
Write-Host "Copied $($p.name) binaries to $destDir"
}

# Copy build integration files from neutron-server
$nsRoot = "$(nsRoot)"

if ($isWinML) {
[xml]$propsXml = Get-Content "$nsRoot/Directory.Packages.props"
$winMLVer = [string]$propsXml.Project.PropertyGroup.WinMLVersion
if ([string]::IsNullOrWhiteSpace($winMLVer)) {
throw "Directory.Packages.props is missing WinMLVersion."
}

$runtimePackageDir = "$(Build.ArtifactStagingDirectory)/winml-runtime-package"
New-Item -ItemType Directory -Path $runtimePackageDir -Force | Out-Null

$nugetArgs = @(
'install', 'Microsoft.Windows.AI.MachineLearning',
'-Version', $winMLVer,
'-Source', 'https://api.nuget.org/v3/index.json',
'-OutputDirectory', $runtimePackageDir,
'-ExcludeVersion',
'-NonInteractive',
'-DirectDownload'
)
Write-Host "Running: nuget $($nugetArgs -join ' ')"
& nuget $nugetArgs
if ($LASTEXITCODE -ne 0) { throw "Failed to download Microsoft.Windows.AI.MachineLearning $winMLVer" }

$runtimePackageRoot = Get-ChildItem $runtimePackageDir -Directory |
Where-Object { $_.Name -like "Microsoft.Windows.AI.MachineLearning*" } |
Select-Object -First 1
if (-not $runtimePackageRoot) {
throw "nuget install did not produce a Microsoft.Windows.AI.MachineLearning package directory in $runtimePackageDir"
}

foreach ($p in $platforms) {
if (-not $p.name.StartsWith("win-")) {
continue
}

$runtimeDll = @(
"$($runtimePackageRoot.FullName)/runtimes/$($p.name)/Microsoft.Windows.AI.MachineLearning.dll",
"$($runtimePackageRoot.FullName)/runtimes/$($p.name)/native/Microsoft.Windows.AI.MachineLearning.dll"
) | Where-Object { Test-Path $_ } | Select-Object -First 1
if ([string]::IsNullOrWhiteSpace($runtimeDll)) {
throw "Microsoft.Windows.AI.MachineLearning $winMLVer does not contain a Microsoft.Windows.AI.MachineLearning.dll for $($p.name)"
}

$destDir = "$unifiedPath/runtimes/$($p.name)/native"
Copy-Item $runtimeDll -Destination $destDir -Force
Write-Host "Copied WinML runtime DLL for $($p.name) to $destDir"
}
}

# Copy build integration files from neutron-server
foreach ($dir in @("build", "buildTransitive")) {
$src = "$nsRoot/src/FoundryLocalCore/Core/$dir"
if (Test-Path $src) {
Expand Down Expand Up @@ -100,10 +143,14 @@ steps:
if ("${{ parameters.isWinML }}" -eq "True") {
$nuspec = "$nsRoot/src/FoundryLocalCore/Core/WinMLNuget.nuspec"
$id = "Microsoft.AI.Foundry.Local.Core.WinML"
$ortVer = $pg.OnnxRuntimeFoundryVersionForWinML
$genaiVer = $pg.OnnxRuntimeGenAIFoundryVersion
$winAppSdkVer = $pg.WinAppSdkVersion
$props = "id=$id;version=$(flcVersion);commitId=$(Build.SourceVersion);OnnxRuntimeFoundryVersionForWinML=$ortVer;OnnxRuntimeGenAIFoundryVersion=$genaiVer;WinAppSdkVersion=$winAppSdkVer"
$ortVer = [string]$pg.OnnxRuntimeFoundryVersionForWinML
$genaiVer = [string]$pg.OnnxRuntimeGenAIFoundryVersion
$winMLVer = [string]$pg.WinMLVersion
if ([string]::IsNullOrWhiteSpace($ortVer)) { throw "Directory.Packages.props is missing OnnxRuntimeFoundryVersionForWinML." }
if ([string]::IsNullOrWhiteSpace($genaiVer)) { throw "Directory.Packages.props is missing OnnxRuntimeGenAIFoundryVersion." }
if ([string]::IsNullOrWhiteSpace($winMLVer)) { throw "Directory.Packages.props is missing WinMLVersion." }

$props = "id=$id;version=$(flcVersion);commitId=$(Build.SourceVersion);OnnxRuntimeFoundryVersionForWinML=$ortVer;OnnxRuntimeGenAIFoundryVersion=$genaiVer;WinMLVersion=$winMLVer"
} else {
$nuspec = "$nsRoot/src/FoundryLocalCore/Core/NativeNuget.nuspec"
$id = "Microsoft.AI.Foundry.Local.Core"
Expand Down Expand Up @@ -266,12 +313,13 @@ steps:
elseif ($parts.Count -eq 2) { "$($parts[0])$($parts[1])" }
else { $parts[0] }

# Both standard and WinML write a deps_versions.json with identical key
# structure. The pipeline produces separate artifacts (deps-versions-standard
# / deps-versions-winml) so SDK stages pick the right one via isWinML.
# The pipeline produces separate dependency version artifacts
# (deps-versions-standard / deps-versions-winml), so SDK stages pick the
# right one via isWinML.
if ($isWinML) {
$deps = @{
'foundry-local-core' = @{ nuget = "$(flcVersion)"; python = $pyVer }
'windows-ai-machinelearning' = @{ version = [string]$pg.WinMLVersion }
onnxruntime = @{ version = [string]$pg.OnnxRuntimeFoundryVersionForWinML }
'onnxruntime-genai' = @{ version = [string]$pg.OnnxRuntimeGenAIFoundryVersion }
}
Expand Down
7 changes: 5 additions & 2 deletions .pipelines/templates/update-deps-versions-steps.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Shared template to update deps_versions.json / deps_versions_winml.json
# from pipeline artifacts. Both files use identical key structure — the
# isWinML parameter determines which file gets overwritten.
# from pipeline artifacts. The isWinML parameter determines which file gets
# overwritten.
parameters:
- name: repoRoot
type: string
Expand Down Expand Up @@ -39,3 +39,6 @@ steps:
Write-Host " FLC Core (Python): $($deps.'foundry-local-core'.python)"
Write-Host " OnnxRuntime: $($deps.onnxruntime.version)"
Write-Host " GenAI: $($deps.'onnxruntime-genai'.version)"
if ($isWinML -and $deps.'windows-ai-machinelearning') {
Write-Host " Windows AI ML: $($deps.'windows-ai-machinelearning'.version)"
}
9 changes: 5 additions & 4 deletions samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ Explore complete working examples that demonstrate how to use Foundry Local —

| Language | Samples | Description |
|----------|---------|-------------|
| [**C#**](cs/) | 13 | .NET SDK samples including native chat, embeddings, audio transcription, tool calling, model management, web server, and tutorials. Uses WinML on Windows for hardware acceleration. |
| [**JavaScript**](js/) | 13 | Node.js SDK samples including native chat, embeddings, audio transcription, Electron desktop app, Copilot SDK integration, LangChain, tool calling, web server, and tutorials. |
| [**Python**](python/) | 10 | Python samples using the OpenAI-compatible API, including chat, embeddings, audio transcription, LangChain integration, tool calling, web server, and tutorials. |
| [**Rust**](rust/) | 9 | Rust SDK samples including native chat, embeddings, audio transcription, tool calling, web server, and tutorials. |
| [**C#**](cs/) | 14 | .NET SDK samples including native chat, embeddings, audio transcription, tool calling, model management, web server, tutorials, and WinML EP verification. Uses WinML on Windows for hardware acceleration. |
| [**JavaScript**](js/) | 14 | Node.js SDK samples including native chat, embeddings, audio transcription, Electron desktop app, Copilot SDK integration, LangChain, tool calling, web server, tutorials, and WinML EP verification. |
| [**Python**](python/) | 11 | Python samples using the OpenAI-compatible API, including chat, embeddings, audio transcription, LangChain integration, tool calling, web server, tutorials, and WinML EP verification. |
| [**Rust**](rust/) | 10 | Rust SDK samples including native chat, embeddings, audio transcription, tool calling, web server, tutorials, and WinML EP verification. |
| [**C++**](cpp/) | 2 | C++ SDK samples including WinML EP verification and live audio transcription. |
10 changes: 10 additions & 0 deletions samples/cpp/verify-winml/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
cmake_minimum_required(VERSION 3.20)

project(VerifyWinMLCpp LANGUAGES CXX)

set(BUILD_TESTING OFF CACHE BOOL "Build C++ SDK tests" FORCE)
add_subdirectory("${CMAKE_CURRENT_LIST_DIR}/../../../sdk/cpp" "${CMAKE_CURRENT_BINARY_DIR}/sdk-cpp")

add_executable(VerifyWinML main.cpp)
target_compile_features(VerifyWinML PRIVATE cxx_std_17)
target_link_libraries(VerifyWinML PRIVATE CppSdk)
40 changes: 40 additions & 0 deletions samples/cpp/verify-winml/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
# Verify WinML 2.0 Execution Providers (C++)

This sample verifies that WinML 2.0 execution providers are correctly
discovered, downloaded, and registered using the Foundry Local C++ SDK. It then
uses registered WinML EP-backed model variants and finishes with one native
streaming chat check.

## Prerequisites

- Windows with a compatible GPU or NPU
- A Foundry Local WinML native runtime copied next to the sample executable

The C++ SDK loads `Microsoft.AI.Foundry.Local.Core.dll` from the executable
directory. Build or install a WinML-enabled SDK/runtime first, then copy the
WinML native binaries next to `VerifyWinML.exe` before running the sample.

## Build

From this directory:

```powershell
cmake -S . -B out\build -G "Visual Studio 18 2026" -A x64 `
-DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" `
-DVCPKG_TARGET_TRIPLET=x64-windows-static-md

cmake --build out\build --config Debug --target VerifyWinML
```

## Run

```powershell
.\out\build\Debug\VerifyWinML.exe
```

## What it tests

1. **EP Discovery** - Lists all available execution providers.
2. **EP Download & Registration** - Downloads and registers the available WinML EPs.
3. **Model Catalog** - Lists text model variants backed by registered accelerated EPs.
4. **Streaming Chat** - Runs streaming chat completion on a WinML EP-backed model via the native C++ SDK.
Loading
Loading