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
4 changes: 2 additions & 2 deletions samples/cs/GettingStarted/Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.AI.Foundry.Local" Version="0.0.0-20251107T104536.7c7026f2" />
<PackageVersion Include="Microsoft.AI.Foundry.Local.WinML" Version="0.0.0-20251107T104548.7c7026f2" />
<PackageVersion Include="Microsoft.AI.Foundry.Local" Version="0.8.0-rc.20251113T180729.6da3214b" />
<PackageVersion Include="Microsoft.AI.Foundry.Local.WinML" Version="0.8.0-rc.20251113T180733.6da3214b" />
<PackageVersion Include="Microsoft.Extensions.Logging" Version="9.0.10" />
<PackageVersion Include="OpenAI" Version="2.5.0" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

<!-- Include the main program -->
<ItemGroup>
<Compile Include="../../src/AudioTranscriptionExample/Program.cs" />
<Compile Include="../../src/AudioTranscriptionExample/*.cs" />
<Compile Include="../../src/Shared/*.cs" />
</ItemGroup>

<!-- Use WinML package for local Foundry SDK on Windows -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

<!-- Include the main program -->
<ItemGroup>
<Compile Include="../../src/FoundryLocalWebServer/Program.cs" />
<Compile Include="../../src/FoundryLocalWebServer/*.cs" />
<Compile Include="../../src/Shared/*.cs" />
</ItemGroup>

<!-- Use WinML package for local Foundry SDK on Windows -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

<!-- Include the main program -->
<ItemGroup>
<Compile Include="../../src/HelloFoundryLocalSdk/Program.cs" />
<Compile Include="../../src/HelloFoundryLocalSdk/*.cs" />
<Compile Include="../../src/Shared/*.cs" />
</ItemGroup>

<!-- Use WinML package for local Foundry SDK on Windows -->
Expand Down
2 changes: 1 addition & 1 deletion samples/cs/GettingStarted/nuget.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<configuration>
<packageSources>
<clear />
<add key="local-feed" value="..\..\..\..\..\..\nugets" />
<add key="local-feed" value="c:\path_to_directory_containing_Foundry_Local_nuget_packages" />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
<packageSourceMapping>
Expand Down
30 changes: 18 additions & 12 deletions samples/cs/GettingStarted/src/AudioTranscriptionExample/Program.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
using Microsoft.AI.Foundry.Local;
using Microsoft.Extensions.Logging;

var config = new Configuration
{
AppName = "my-audio-app",
LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Debug
AppName = "foundry_local_samples",
LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information
};

using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
});
var logger = loggerFactory.CreateLogger<Program>();

// Initialize the singleton instance.
await FoundryLocalManager.CreateAsync(config, logger);
await FoundryLocalManager.CreateAsync(config, Utils.GetAppLogger());
var mgr = FoundryLocalManager.Instance;


// Ensure that any Execution Provider (EP) downloads run and are completed.
// EP packages include dependencies and may be large.
// Download is only required again if a new version of the EP is released.
// For cross platform builds there is no dynamic EP download and this will return immediately.
await Utils.RunWithSpinner("Registering execution providers", mgr.EnsureEpsDownloadedAsync());


// Get the model catalog
var catalog = await mgr.GetCatalogAsync();


// Get a model using an alias
var model = await catalog.GetModelAsync("whisper-tiny") ?? throw new System.Exception("Model not found");


// Download the model (the method skips download if already cached)
await model.DownloadAsync(progress =>
{
Expand All @@ -33,26 +37,28 @@ await model.DownloadAsync(progress =>
}
});


// Load the model
Console.Write($"Loading model {model.Id}...");
await model.LoadAsync();
Console.WriteLine("done.");


// Get a chat client
var audioClient = await model.GetAudioClientAsync();

// get a cancellation token
CancellationToken ct = new CancellationToken();

// Get a transcription with streaming outputs
Console.WriteLine("Transcribing audio with streaming output:");
var response = audioClient.TranscribeAudioStreamingAsync("Recording.mp3", ct);
var response = audioClient.TranscribeAudioStreamingAsync("Recording.mp3", CancellationToken.None);
await foreach (var chunk in response)
{
Console.Write(chunk.Text);
Console.Out.Flush();
}

Console.WriteLine();


// Tidy up - unload the model
await model.UnloadAsync();
29 changes: 15 additions & 14 deletions samples/cs/GettingStarted/src/FoundryLocalWebServer/Program.cs
Original file line number Diff line number Diff line change
@@ -1,36 +1,36 @@
using Microsoft.AI.Foundry.Local;
using Microsoft.Extensions.Logging;
using OpenAI;
using System.ClientModel;

var config = new Configuration
{
AppName = "my-app-name",
LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Debug,
AppName = "foundry_local_samples",
LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information,
Web = new Configuration.WebService
{
Urls = "http://127.0.0.1:55588"
}
};

using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
});

var logger = loggerFactory.CreateLogger<Program>();

// Initialize the singleton instance.
await FoundryLocalManager.CreateAsync(config, logger);
await FoundryLocalManager.CreateAsync(config, Utils.GetAppLogger());
var mgr = FoundryLocalManager.Instance;


// Ensure that any Execution Provider (EP) downloads run and are completed.
// EP packages include dependencies and may be large.
// Download is only required again if a new version of the EP is released.
// For cross platform builds there is no dynamic EP download and this will return immediately.
await Utils.RunWithSpinner("Registering execution providers", mgr.EnsureEpsDownloadedAsync());


// Get the model catalog
var catalog = await mgr.GetCatalogAsync();

// Get a model using an alias
//var model = await catalog.GetModelAsync("qwen2.5-0.5b") ?? throw new Exception("Model not found");
var model = await catalog.GetModelVariantAsync("qwen2.5-0.5b-instruct-generic-cpu:3") ?? throw new Exception("Model not found");

// Get a model using an alias
var model = await catalog.GetModelAsync("qwen2.5-0.5b") ?? throw new Exception("Model not found");
// Download the model (the method skips download if already cached)
await model.DownloadAsync(progress =>
{
Expand All @@ -41,11 +41,13 @@ await model.DownloadAsync(progress =>
}
});


// Load the model
Console.Write($"Loading model {model.Id}...");
await model.LoadAsync();
Console.WriteLine("done.");


// Start the web service
Console.Write($"Starting web service on {config.Web.Urls}...");
await mgr.StartWebServiceAsync();
Expand All @@ -61,7 +63,6 @@ await model.DownloadAsync(progress =>
});

var chatClient = client.GetChatClient(model.Id);

var completionUpdates = chatClient.CompleteChatStreaming("Why is the sky blue?");

Console.Write($"[ASSISTANT]: ");
Expand Down
70 changes: 54 additions & 16 deletions samples/cs/GettingStarted/src/HelloFoundryLocalSdk/Program.cs
Original file line number Diff line number Diff line change
@@ -1,28 +1,32 @@
using Microsoft.AI.Foundry.Local;
using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels;
using Microsoft.Extensions.Logging;
using System.Diagnostics;

CancellationToken ct = new CancellationToken();

var config = new Configuration
{
AppName = "my-app-name",
LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Debug
AppName = "foundry_local_samples",
LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information
};

using var loggerFactory = LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Debug);
});
var logger = loggerFactory.CreateLogger<Program>();

// Initialize the singleton instance.
await FoundryLocalManager.CreateAsync(config, logger);
await FoundryLocalManager.CreateAsync(config, Utils.GetAppLogger());
var mgr = FoundryLocalManager.Instance;


// Ensure that any Execution Provider (EP) downloads run and are completed.
// EP packages include dependencies and may be large.
// Download is only required again if a new version of the EP is released.
// For cross platform builds there is no dynamic EP download and this will return immediately.
await Utils.RunWithSpinner("Registering execution providers", mgr.EnsureEpsDownloadedAsync());


// Get the model catalog
var catalog = await mgr.GetCatalogAsync();


// List available models
Console.WriteLine("Available models for your hardware:");
var models = await catalog.ListModelsAsync();
Expand All @@ -34,21 +38,55 @@
}
}

// Get a model using an alias
//var model = await catalog.GetModelAsync("qwen2.5-0.5b") ?? throw new Exception("Model not found");
var model = await catalog.GetModelVariantAsync("qwen2.5-0.5b-instruct-generic-cpu:3") ?? throw new Exception("Model not found");

// is model cached
Console.WriteLine($"Is model cached: {await model.IsCachedAsync()}");

// print out cached models
var cachedModels = await catalog.GetCachedModelsAsync();
Console.WriteLine("Cached models:");
Console.WriteLine("\nCached models:");
foreach (var cachedModel in cachedModels)
{
Console.WriteLine($"- {cachedModel.Alias} ({cachedModel.Id})");
}


// Get a model using an alias.
var model = await catalog.GetModelAsync("qwen2.5-0.5b") ?? throw new Exception("Model not found");

// `model.SelectedVariant` indicates which variant will be used by default.
//
// Models in Model.Variants are ordered by priority, with the highest priority first.
// The first downloaded model is selected by default.
// The highest priority is selected if no models have been downloaded.
Console.WriteLine("\nThe default selected model variant is: " + model.Id);
if (model.SelectedVariant != model.Variants.First())
{
Debug.Assert(await model.SelectedVariant.IsCachedAsync());
Console.WriteLine("The model variant was selected due to being locally cached.");
}


// OPTIONAL: `model` can be used directly and `model.SelectedVariant` will be used as the default.
// You can explicitly select or use a specific ModelVariant if you want more control
// over the device and/or execution provider used.
// Model and ModelVariant can be used interchangeably in methods such as
// DownloadAsync, LoadAsync, UnloadAsync and GetChatClientAsync.
//
// Choices:
// - Use a ModelVariant directly from the catalog if you know the variant Id
// - `var modelVariant = await catalog.GetModelVariantAsync("qwen2.5-0.5b-instruct-generic-gpu:3")`
//
// - Get the ModelVariant from Model.Variants
// - `var modelVariant = model.Variants.First(v => v.Id == "qwen2.5-0.5b-instruct-generic-cpu:4")`
// - `var modelVariant = model.Variants.First(v => v.Info.Runtime?.DeviceType == DeviceType.GPU)`
// - optional: update selected variant in `model` using `model.SelectVariant(modelVariant);` if you wish to use
// `model` in your code.

// For this example we explicitly select the CPU variant, and call SelectVariant so all the following example code
// uses the `model` instance.
Console.WriteLine("Selecting CPU variant of model");
var modelVariant = model.Variants.First(v => v.Info.Runtime?.DeviceType == DeviceType.CPU);
model.SelectVariant(modelVariant);


// Download the model (the method skips download if already cached)
await model.DownloadAsync(progress =>
{
Expand Down
54 changes: 54 additions & 0 deletions samples/cs/GettingStarted/src/Shared/Utils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
using Microsoft.Extensions.Logging;
using System.Text;

internal static class Utils
{
private static readonly ILoggerFactory _loggerFactory;

static Utils()
{
_loggerFactory = Microsoft.Extensions.Logging.LoggerFactory.Create(builder =>
{
builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information);
});
}

/// <summary>
/// Get a dummy application logger.
/// </summary>
/// <returns>ILogger</returns>
internal static ILogger GetAppLogger()
{
return _loggerFactory.CreateLogger("FoundryLocalSamples");
}

internal static async Task RunWithSpinner<T>(string msg, T workTask) where T : Task
{
// Start the spinner
using var cts = new CancellationTokenSource();
var spinnerTask = ShowSpinner(msg, cts.Token);

await workTask; // wait for the real work to finish
cts.Cancel(); // stop the spinner
await spinnerTask; // wait for spinner to exit
}

private static async Task ShowSpinner(string msg, CancellationToken token)
{
Console.OutputEncoding = Encoding.UTF8;

var sequence = new[] { '◴','◷','◶','◵' };

int counter = 0;

while (!token.IsCancellationRequested)
{
Console.Write($"{msg}\t{sequence[counter % sequence.Length]}");
Console.SetCursorPosition(0, Console.CursorTop);
counter++;
await Task.Delay(200, token).ContinueWith(_ => { });
}

Console.WriteLine($"\nDone.\n");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- For Windows use the following -->
<TargetFramework>net8.0-windows10.0.26100</TargetFramework>
<TargetFramework>net9.0-windows10.0.26100</TargetFramework>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
<Platforms>ARM64;x64</Platforms>
</PropertyGroup>

<ItemGroup>
<Compile Include="../../src/AudioTranscriptionExample/Program.cs" />
<Compile Include="../../src/AudioTranscriptionExample/*.cs" />
<Compile Include="../../src/Shared/*.cs" />
</ItemGroup>

<!-- Use WinML package for local Foundry SDK on Windows -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<!-- For Windows use the following -->
<TargetFramework>net8.0-windows10.0.26100</TargetFramework>
<TargetFramework>net9.0-windows10.0.26100</TargetFramework>
<WindowsAppSDKSelfContained>true</WindowsAppSDKSelfContained>
<Platforms>x64;ARM64</Platforms>
</PropertyGroup>

<ItemGroup>
<Compile Include="../../src/FoundryLocalWebServer/Program.cs" />
<Compile Include="../../src/FoundryLocalWebServer/*.cs" />
<Compile Include="../../src/Shared/*.cs" />
</ItemGroup>

<!-- Use WinML package for local Foundry SDK on Windows -->
Expand Down
Loading