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
25 changes: 7 additions & 18 deletions SUPPORT.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,14 @@
# TODO: The maintainer of this repo has not yet edited this file

**REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project?

- **No CSS support:** Fill out this template with information about how to file issues and get help.
- **Yes CSS support:** Fill out an intake form at [aka.ms/onboardsupport](https://aka.ms/onboardsupport). CSS will work with/help you to determine next steps.
- **Not sure?** Fill out an intake as though the answer were "Yes". CSS will help you decide.

*Then remove this first heading from this SUPPORT.MD file before publishing your repo.*

# Support

## How to file issues and get help
## How to file issues and get help

This project uses GitHub Issues to track bugs and feature requests. Please search the existing
issues before filing new issues to avoid duplicates. For new issues, file your bug or
This project uses GitHub Issues to track bugs and feature requests. Please search the existing
issues before filing new issues to avoid duplicates. For new issues, file your bug or
feature request as a new Issue.

For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE
FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER
CHANNEL. WHERE WILL YOU HELP PEOPLE?**.
For help and questions about using Foundry Local, please refer to the [documentation](docs/README.md)
and the [samples](samples/) in this repository.

## Microsoft Support Policy
## Microsoft Support Policy

Support for this **PROJECT or PRODUCT** is limited to the resources listed above.
Support for Foundry Local is limited to the resources listed above.
29 changes: 20 additions & 9 deletions samples/cs/GettingStarted/src/AudioTranscriptionExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,21 +29,32 @@
model.SelectVariant(modelVariant);


// Download the model (the method skips download if already cached)
await model.DownloadAsync(progress =>
// Download the model (check cache first)
if (!await model.IsCachedAsync())
{
Console.Write($"\rDownloading model: {progress:F2}%");
if (progress >= 100f)
Console.WriteLine($"Model \"{model.Id}\" not found in cache. Downloading...");
await model.DownloadAsync(progress =>
{
Console.WriteLine();
}
});
var filled = (int)Math.Round(progress / 100.0 * 30);
var bar = new string('\u2588', filled) + new string('\u2591', 30 - filled);
Console.Write($"\rDownloading: [{bar}] {progress:F1}%");
if (progress >= 100f)
{
Console.WriteLine();
}
});
Console.WriteLine("\u2713 Model downloaded");
}
else
{
Console.WriteLine($"\u2713 Model \"{model.Id}\" already cached \u2014 skipping download");
}


// Load the model
// Load the model into memory
Console.Write($"Loading model {model.Id}...");
await model.LoadAsync();
Console.WriteLine("done.");
Console.WriteLine("done. \u2713 Model ready");


// Get a chat client
Expand Down
30 changes: 21 additions & 9 deletions samples/cs/GettingStarted/src/FoundryLocalWebServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,33 @@

// 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 =>

// Check cache before downloading — skip download if model is already cached
if (!await model.IsCachedAsync())
{
Console.Write($"\rDownloading model: {progress:F2}%");
if (progress >= 100f)
Console.WriteLine($"Model \"{model.Id}\" not found in cache. Downloading...");
await model.DownloadAsync(progress =>
{
Console.WriteLine();
}
});
var filled = (int)Math.Round(progress / 100.0 * 30);
var bar = new string('\u2588', filled) + new string('\u2591', 30 - filled);
Console.Write($"\rDownloading: [{bar}] {progress:F1}%");
if (progress >= 100f)
{
Console.WriteLine();
}
});
Console.WriteLine("\u2713 Model downloaded");
}
else
{
Console.WriteLine($"\u2713 Model \"{model.Id}\" already cached \u2014 skipping download");
}


// Load the model
// Load the model into memory
Console.Write($"Loading model {model.Id}...");
await model.LoadAsync();
Console.WriteLine("done.");
Console.WriteLine("done. \u2713 Model ready");


// Start the web service
Expand Down
29 changes: 20 additions & 9 deletions samples/cs/GettingStarted/src/HelloFoundryLocalSdk/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,20 +29,31 @@
// 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 =>
// Check cache before downloading — skip download if model is already cached
if (!await model.IsCachedAsync())
{
Console.Write($"\rDownloading model: {progress:F2}%");
if (progress >= 100f)
Console.WriteLine($"Model \"{model.Id}\" not found in cache. Downloading...");
await model.DownloadAsync(progress =>
{
Console.WriteLine();
}
});
var filled = (int)Math.Round(progress / 100.0 * 30);
var bar = new string('\u2588', filled) + new string('\u2591', 30 - filled);
Console.Write($"\rDownloading: [{bar}] {progress:F1}%");
if (progress >= 100f)
{
Console.WriteLine();
}
});
Console.WriteLine("\u2713 Model downloaded");
}
else
{
Console.WriteLine($"\u2713 Model \"{model.Id}\" already cached \u2014 skipping download");
}

// Load the model
// Load the model into memory
Console.Write($"Loading model {model.Id}...");
await model.LoadAsync();
Console.WriteLine("done.");
Console.WriteLine("done. \u2713 Model ready");

// Get a chat client
var chatClient = await model.GetChatClientAsync();
Expand Down
29 changes: 21 additions & 8 deletions samples/cs/GettingStarted/src/ModelManagementExample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,18 +89,31 @@
model.SelectVariant(modelVariant);


// Download the model (the method skips download if already cached)
await model.DownloadAsync(progress =>
// Download the model (check cache first)
if (!await model.IsCachedAsync())
{
Console.Write($"\rDownloading model: {progress:F2}%");
if (progress >= 100f)
Console.WriteLine($"Model \"{model.Id}\" not found in cache. Downloading...");
await model.DownloadAsync(progress =>
{
Console.WriteLine();
}
});
var filled = (int)Math.Round(progress / 100.0 * 30);
var bar = new string('\u2588', filled) + new string('\u2591', 30 - filled);
Console.Write($"\rDownloading: [{bar}] {progress:F1}%");
if (progress >= 100f)
{
Console.WriteLine();
}
});
Console.WriteLine("\u2713 Model downloaded");
}
else
{
Console.WriteLine($"\u2713 Model \"{model.Id}\" already cached \u2014 skipping download");
}

// Load the model
// Load the model into memory
Console.Write($"Loading model {model.Id}...");
await model.LoadAsync();
Console.WriteLine("done. \u2713 Model ready");


// List loaded models (i.e. in memory) from the catalog
Expand Down
30 changes: 20 additions & 10 deletions samples/cs/GettingStarted/src/ToolCallingFoundryLocalSdk/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,22 +32,32 @@
// 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 =>
// Check cache before downloading — skip download if model is already cached
if (!await model.IsCachedAsync())
{
Console.Write($"\rDownloading model: {progress:F2}%");
if (progress >= 100f)
Console.WriteLine($"Model \"{model.Id}\" not found in cache. Downloading...");
await model.DownloadAsync(progress =>
{
Console.WriteLine();
}
});
var filled = (int)Math.Round(progress / 100.0 * 30);
var bar = new string('\u2588', filled) + new string('\u2591', 30 - filled);
Console.Write($"\rDownloading: [{bar}] {progress:F1}%");
if (progress >= 100f)
{
Console.WriteLine();
}
});
Console.WriteLine("\u2713 Model downloaded");
}
else
{
Console.WriteLine($"\u2713 Model \"{model.Id}\" already cached \u2014 skipping download");
}


// Load the model
// Load the model into memory
Console.Write($"Loading model {model.Id}...");
await model.LoadAsync();
Console.WriteLine("done.");
Console.WriteLine("done. \u2713 Model ready");


// Get a chat client
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,21 +33,33 @@

// 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 =>

// Check cache before downloading — skip download if model is already cached
if (!await model.IsCachedAsync())
{
Console.Write($"\rDownloading model: {progress:F2}%");
if (progress >= 100f)
Console.WriteLine($"Model \"{model.Id}\" not found in cache. Downloading...");
await model.DownloadAsync(progress =>
{
Console.WriteLine();
}
});
var filled = (int)Math.Round(progress / 100.0 * 30);
var bar = new string('\u2588', filled) + new string('\u2591', 30 - filled);
Console.Write($"\rDownloading: [{bar}] {progress:F1}%");
if (progress >= 100f)
{
Console.WriteLine();
}
});
Console.WriteLine("\u2713 Model downloaded");
}
else
{
Console.WriteLine($"\u2713 Model \"{model.Id}\" already cached \u2014 skipping download");
}


// Load the model
// Load the model into memory
Console.Write($"Loading model {model.Id}...");
await model.LoadAsync();
Console.WriteLine("done.");
Console.WriteLine("done. \u2713 Model ready");


// Start the web service
Expand Down
28 changes: 28 additions & 0 deletions samples/cs/whisper-transcription/Health/FoundryHealthCheck.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Microsoft.Extensions.Diagnostics.HealthChecks;

namespace WhisperTranscription;

public class FoundryHealthCheck : IHealthCheck
{
private readonly FoundryModelService _modelService;

public FoundryHealthCheck(FoundryModelService modelService)
{
_modelService = modelService;
}

public async Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context,
CancellationToken cancellationToken = default)
{
try
{
var model = await _modelService.GetModelAsync();
return HealthCheckResult.Healthy($"Model available: {model.Id}");
}
catch (Exception ex)
{
return HealthCheckResult.Unhealthy("Foundry Local unavailable", ex);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Net;
using System.Text.Json;

namespace WhisperTranscription;

public class ErrorHandlingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ErrorHandlingMiddleware> _logger;

public ErrorHandlingMiddleware(RequestDelegate next, ILogger<ErrorHandlingMiddleware> logger)
{
_next = next;
_logger = logger;
}

public async Task InvokeAsync(HttpContext context)
{
try
{
await _next(context);
}
catch (Exception ex)
{
_logger.LogError(ex, "Unhandled exception");
context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
context.Response.ContentType = "application/json";
var payload = JsonSerializer.Serialize(new { error = "An unexpected error occurred." });
await context.Response.WriteAsync(payload);
}
}
}
Loading