Skip to content

Add named regions and tutorial samples for docs externalization#563

Open
samuel100 wants to merge 13 commits intomainfrom
samuel100/doc-samples
Open

Add named regions and tutorial samples for docs externalization#563
samuel100 wants to merge 13 commits intomainfrom
samuel100/doc-samples

Conversation

@samuel100
Copy link
Copy Markdown
Contributor

To ensure that our docs on MS Learn have accurate code samples, we will update the docs so they consume the code from this repo. In this repo, we will run a test to ensure that the samples work - if there is a break in the samples then this should be fix before a PR can be merged in.

  • Add named regions to 15 existing sample files (CS, JS, Python, Rust)
  • Create 3 missing Python samples (audio-transcription, web-server, langchain-integration)
  • Create 16 tutorial sample projects (4 tutorials x 4 languages)
  • Add samples-integration-test.yml CI workflow

- Add named regions to 15 existing sample files (CS, JS, Python, Rust)
- Create 3 missing Python samples (audio-transcription, web-server, langchain-integration)
- Create 16 tutorial sample projects (4 tutorials x 4 languages)
- Add samples-integration-test.yml CI workflow

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 30, 2026 11:12
@vercel
Copy link
Copy Markdown

vercel bot commented Mar 30, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
foundry-local Ready Ready Preview, Comment Mar 30, 2026 5:12pm

Request Review

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR externalizes code samples for MS Learn by adding named regions, introducing missing tutorial/sample projects across Rust/JS/Python/C#, and adding a CI workflow to build/run samples to prevent drift.

Changes:

  • Added named region markers (<imports>, <init>, etc.) to existing samples so docs can pull snippets from the repo.
  • Added new tutorial sample projects across Rust/JS/Python/C# (voice-to-text, tool-calling, document summarizer, chat assistant).
  • Added a GitHub Actions workflow to build/run samples as an integration check.

Reviewed changes

Copilot reviewed 54 out of 54 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
samples/rust/tutorial-voice-to-text/src/main.rs New Rust tutorial sample with regions for transcription + summarization
samples/rust/tutorial-voice-to-text/Cargo.toml New Rust tutorial manifest
samples/rust/tutorial-tool-calling/src/main.rs New Rust tool-calling tutorial sample with local tool execution
samples/rust/tutorial-tool-calling/Cargo.toml New Rust tutorial manifest with serde_json
samples/rust/tutorial-document-summarizer/src/main.rs New Rust document summarizer tutorial sample with file/dir handling
samples/rust/tutorial-document-summarizer/Cargo.toml New Rust tutorial manifest
samples/rust/tutorial-chat-assistant/src/main.rs New Rust chat assistant tutorial sample with streaming
samples/rust/tutorial-chat-assistant/Cargo.toml New Rust tutorial manifest
samples/rust/tool-calling-foundry-local/src/main.rs Added named regions around imports/init/tools/loop/cleanup
samples/rust/native-chat-completions/src/main.rs Added named regions around init/model/chat/streaming/cleanup
samples/rust/foundry-local-webserver/src/main.rs Added named regions around init/model/server setup
samples/rust/audio-transcription-example/src/main.rs Added named regions around init/model/transcription/cleanup
samples/python/web-server/src/app.py New Python sample using OpenAI client against local REST endpoint
samples/python/web-server/requirements.txt Python dependencies for web-server sample
samples/python/tutorial-voice-to-text/src/app.py New Python tutorial voice-to-text (transcribe then summarize)
samples/python/tutorial-voice-to-text/requirements.txt Python dependencies for tutorial voice-to-text
samples/python/tutorial-tool-calling/src/app.py New Python tutorial tool-calling loop with tool execution
samples/python/tutorial-tool-calling/requirements.txt Python dependencies for tutorial tool-calling
samples/python/tutorial-document-summarizer/src/app.py New Python tutorial for summarizing file(s)
samples/python/tutorial-document-summarizer/requirements.txt Python dependencies for tutorial doc summarizer
samples/python/tutorial-chat-assistant/src/app.py New Python tutorial chat assistant with streaming loop
samples/python/tutorial-chat-assistant/requirements.txt Python dependencies for tutorial chat assistant
samples/python/summarize/summarize.py Added named regions around imports/init/summarize
samples/python/langchain-integration/src/app.py New Python LangChain integration sample targeting local endpoint
samples/python/langchain-integration/requirements.txt Python dependencies for LangChain integration
samples/python/hello-foundry-local/src/app.py Added named regions around imports/init/openai client/streaming
samples/python/audio-transcription/src/app.py New Python audio transcription sample
samples/python/audio-transcription/requirements.txt Python dependencies for audio transcription sample
samples/js/web-server-example/app.js Added named regions around imports/init/model/server setup
samples/js/tutorial-voice-to-text/package.json New JS tutorial package manifest
samples/js/tutorial-voice-to-text/app.js New JS tutorial voice-to-text sample with regions
samples/js/tutorial-tool-calling/package.json New JS tutorial package manifest
samples/js/tutorial-tool-calling/app.js New JS tutorial tool-calling loop with regions
samples/js/tutorial-document-summarizer/package.json New JS tutorial package manifest
samples/js/tutorial-document-summarizer/app.js New JS tutorial document summarizer sample with regions
samples/js/tutorial-chat-assistant/package.json New JS tutorial package manifest
samples/js/tutorial-chat-assistant/app.js New JS tutorial chat assistant sample with streaming regions
samples/js/tool-calling-foundry-local/src/app.js Added named regions around imports/init/model/tool loop/cleanup
samples/js/native-chat-completions/app.js Added named regions around init/model/chat/streaming/cleanup
samples/js/langchain-integration-example/app.js Added named regions around init/langchain/chat completion
samples/js/audio-transcription-example/app.js Added named regions around init/model/transcription/cleanup
samples/cs/GettingStarted/src/TutorialVoiceToText/TutorialVoiceToText.csproj New C# tutorial project for voice-to-text
samples/cs/GettingStarted/src/TutorialVoiceToText/Program.cs New C# voice-to-text tutorial with transcription + summarization
samples/cs/GettingStarted/src/TutorialToolCalling/TutorialToolCalling.csproj New C# tutorial project for tool-calling
samples/cs/GettingStarted/src/TutorialToolCalling/Program.cs New C# tool-calling tutorial sample
samples/cs/GettingStarted/src/TutorialDocumentSummarizer/TutorialDocumentSummarizer.csproj New C# tutorial project for document summarizer
samples/cs/GettingStarted/src/TutorialDocumentSummarizer/Program.cs New C# document summarizer tutorial sample
samples/cs/GettingStarted/src/TutorialChatAssistant/TutorialChatAssistant.csproj New C# tutorial project for chat assistant
samples/cs/GettingStarted/src/TutorialChatAssistant/Program.cs New C# chat assistant tutorial with streaming
samples/cs/GettingStarted/src/ToolCallingFoundryLocalSdk/Program.cs Added named regions around init/model/tools/loop/cleanup
samples/cs/GettingStarted/src/HelloFoundryLocalSdk/Program.cs Added named regions around init/model/chat/cleanup
samples/cs/GettingStarted/src/FoundryLocalWebServer/Program.cs Added named regions around init/model/server setup
samples/cs/GettingStarted/src/AudioTranscriptionExample/Program.cs Added named regions around init/model/transcription/cleanup
.github/workflows/samples-integration-test.yml New CI workflow to build/run samples across languages
Comments suppressed due to low confidence (14)

samples/rust/tutorial-voice-to-text/Cargo.toml:1

  • The relative path to the Rust SDK looks incorrect for a project under samples/rust/... (it resolves to samples/sdk/rust). Update it to point to the repo-root sdk/rust (e.g., ../../../sdk/rust) so cargo build works in CI.
    samples/rust/tutorial-tool-calling/Cargo.toml:1
  • The foundry-local-sdk path likely resolves to samples/sdk/rust from this location. Use the correct relative path to the repo-root sdk/rust (e.g., ../../../sdk/rust) to prevent cargo build failures.
    samples/rust/tutorial-document-summarizer/Cargo.toml:1
  • This path appears to point to samples/sdk/rust rather than the repo-root sdk/rust. Adjust to the correct relative path (commonly ../../../sdk/rust from samples/rust/<project>).
    samples/python/tutorial-tool-calling/src/app.py:1
  • This app builds messages as a list of dicts, but messages.append(choice) appends an SDK message object. Mixing message types is likely to break serialization inside client.complete_chat(...). Convert choice into the same wire format as the rest of the list (or keep the entire conversation in SDK message objects) before re-sending.
    samples/python/tutorial-tool-calling/src/app.py:1
  • Using eval() on user-provided input is unsafe and can enable denial-of-service (e.g., very large exponentiation) even with character allowlists. Prefer a small expression parser (similar to the Rust sample) or Python’s ast-based evaluation of a restricted grammar.
    samples/python/tutorial-voice-to-text/src/app.py:1
  • This relies on meeting-notes.wav being present in the current working directory. In the integration workflow, samples are launched from the repo root, so this will likely fail with a missing file. Consider accepting a CLI argument and/or resolving the default audio path relative to __file__ (and ensuring the test harness provides the asset).
    samples/rust/tool-calling-foundry-local/src/main.rs:1
  • The section headers have missing spaces (e.g., 'Load a model────────────────' and 'clientwith'). Add the missing spaces to keep the rendered docs readable.
    samples/rust/tool-calling-foundry-local/src/main.rs:1
  • The section headers have missing spaces (e.g., 'Load a model────────────────' and 'clientwith'). Add the missing spaces to keep the rendered docs readable.
    samples/rust/native-chat-completions/src/main.rs:1
  • Several section headers lost spaces (e.g., 'modeland', 'Non-streamingchat', 'Unloadthe'). Fixing these improves readability for docs that consume these snippets.
    samples/rust/native-chat-completions/src/main.rs:1
  • Several section headers lost spaces (e.g., 'modeland', 'Non-streamingchat', 'Unloadthe'). Fixing these improves readability for docs that consume these snippets.
    samples/rust/native-chat-completions/src/main.rs:1
  • Several section headers lost spaces (e.g., 'modeland', 'Non-streamingchat', 'Unloadthe'). Fixing these improves readability for docs that consume these snippets.
    samples/rust/native-chat-completions/src/main.rs:1
  • Several section headers lost spaces (e.g., 'modeland', 'Non-streamingchat', 'Unloadthe'). Fixing these improves readability for docs that consume these snippets.
    samples/rust/audio-transcription-example/src/main.rs:1
  • The comment header is missing a space ('whispermodel'). Insert the space to keep the docs output clean.
    samples/python/web-server/src/app.py:1
  • Python samples in this PR use both foundry_local_sdk and foundry_local import paths. To reduce confusion and avoid import breakage, standardize on a single import style across samples (whichever the built-from-source wheel guarantees), and align all new samples accordingly.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

<ItemGroup>
<PackageReference Include="Microsoft.AI.Foundry.Local" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.10" />
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The corresponding Program.cs uses Betalgo.Ranul.OpenAI.ObjectModels.RequestModels, but this project file doesn’t reference the required NuGet package. Add the appropriate Betalgo.Ranul.OpenAI package reference (or remove the dependency from the sample code) so the project builds in the CI job.

Suggested change
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.10" />
<PackageReference Include="Betalgo.Ranul.OpenAI" Version="*" />

Copilot uses AI. Check for mistakes.
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AI.Foundry.Local" Version="1.0.0" />
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This tutorial’s Program.cs imports Betalgo.Ranul.OpenAI... types, but the project file does not include that NuGet dependency. Add the missing package reference (or refactor the sample to use only Foundry Local SDK types) to avoid build failures.

Suggested change
<PackageReference Include="Microsoft.AI.Foundry.Local" Version="1.0.0" />
<PackageReference Include="Microsoft.AI.Foundry.Local" Version="1.0.0" />
<PackageReference Include="Betalgo.OpenAI" Version="8.5.0" />

Copilot uses AI. Check for mistakes.
<ItemGroup>
<PackageReference Include="Microsoft.AI.Foundry.Local" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.10" />
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Program.cs imports Betalgo.Ranul.OpenAI.ObjectModels.RequestModels, but the csproj doesn’t include that dependency. Add the required NuGet package reference so CI builds succeed.

Suggested change
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.10" />
<PackageReference Include="Betalgo.Ranul.OpenAI" Version="*" />

Copilot uses AI. Check for mistakes.
<ItemGroup>
<PackageReference Include="Microsoft.AI.Foundry.Local" Version="1.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.10" />
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The chat assistant tutorial code uses Betalgo.Ranul.OpenAI request model types, but the project file doesn’t reference that package. Add the missing PackageReference (or remove that dependency from the code) to keep the samples buildable.

Suggested change
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.10" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="9.0.10" />
<PackageReference Include="Betalgo.OpenAI" Version="8.0.0" />

Copilot uses AI. Check for mistakes.
Comment on lines +68 to +70
const result = Function(
`"use strict"; return (${expression})`
)();
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Evaluating user-provided expressions via Function(...) is risky and can lead to denial-of-service or unexpected behavior. Consider replacing this with a small safe expression parser (or a library designed for safe math evaluation) rather than executing generated code.

Copilot uses AI. Check for mistakes.
Comment on lines +29 to +31
const transcription = await audioClient.transcribe(
'./meeting-notes.wav'
);
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default audio path is relative to the process working directory, which may not be the sample’s directory when run from CI. Prefer resolving relative to the script location (or accept a CLI arg) and ensure the integration test provides the audio file.

Copilot uses AI. Check for mistakes.
Comment on lines +83 to +87
try {
$proc = Start-Process python -ArgumentList $sample.FullName -NoNewWindow -PassThru -Wait -RedirectStandardOutput "stdout.txt" -RedirectStandardError "stderr.txt"
if ($proc.ExitCode -ne 0) {
Write-Host "FAILED (exit code $($proc.ExitCode))"
Get-Content stderr.txt | Write-Host
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Samples are executed with the runner’s working directory (repo root), so any sample that expects local assets or relative paths from its own folder will fail. Run each sample with -WorkingDirectory $sample.DirectoryName (and/or pass required fixture paths as arguments) to make execution deterministic in CI.

Suggested change
try {
$proc = Start-Process python -ArgumentList $sample.FullName -NoNewWindow -PassThru -Wait -RedirectStandardOutput "stdout.txt" -RedirectStandardError "stderr.txt"
if ($proc.ExitCode -ne 0) {
Write-Host "FAILED (exit code $($proc.ExitCode))"
Get-Content stderr.txt | Write-Host
$stdoutPath = Join-Path $sample.DirectoryName "stdout.txt"
$stderrPath = Join-Path $sample.DirectoryName "stderr.txt"
try {
$proc = Start-Process python -ArgumentList $sample.FullName -WorkingDirectory $sample.DirectoryName -NoNewWindow -PassThru -Wait -RedirectStandardOutput $stdoutPath -RedirectStandardError $stderrPath
if ($proc.ExitCode -ne 0) {
Write-Host "FAILED (exit code $($proc.ExitCode))"
Get-Content $stderrPath | Write-Host

Copilot uses AI. Check for mistakes.
# Install dependencies if package.json exists
$pkgJson = Join-Path $sample.DirectoryName "package.json"
if (Test-Path $pkgJson) {
Push-Location $sample.DirectoryName
Copy link

Copilot AI Mar 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow builds sdk/js from source, but the samples install foundry-local-sdk via npm install from the registry (e.g., *), so CI may not validate the SDK code in this repo. To ensure samples validate the in-repo SDK, update sample dependencies to use a local file: reference (or use npm workspaces) and install from the workspace during CI.

Suggested change
Push-Location $sample.DirectoryName
Push-Location $sample.DirectoryName
npm install "foundry-local-sdk@file:$env:GITHUB_WORKSPACE/sdk/js"

Copilot uses AI. Check for mistakes.
- Add 4 tutorial crates to samples/rust/Cargo.toml workspace members
- Fix C# .csproj files: remove Version attrs (use CPM), target net9.0
- Add Microsoft.Extensions.Logging.Console to Directory.Packages.props
- Rewrite CI to do build/syntax checks instead of runtime execution
  (no model runtime available in CI)
- JS: build SDK from source and npm link for syntax checks
- Rust: build workspace instead of individual manifests

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Three tutorial Cargo.toml files had wrong relative path depth
to the SDK crate. Path needs 3 parent levels (tutorial dir ->
rust dir -> samples dir -> repo root), not 2.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- nuget.config: Add NuGet.org as primary source with package source
  mapping (Foundry/OnnxRuntime -> ORT-Nightly, everything else -> NuGet.org)
- Add complete_code region to ToolCallingFoundryLocalWebServer/Program.cs
  (fixes docs build warning: invalid-code)
- Remove legacy samples: samples/rag, samples/python/summarize
- CI: Remove redundant NuGet config step, skip windows-only projects on macOS

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The published NuGet package (0.9.0-dev) on ORT-Nightly is older
than the SDK source and lacks ToolChoice and the 3-arg
CompleteChatStreamingAsync overload.

- CI now packs sdk/cs/ into local-packages/ before building samples
- nuget.config: Added local-sdk source for Microsoft.AI.Foundry.Local*
  packages, NuGet.org for standard packages, ORT-Nightly for Core/OnnxRuntime
- Install both .NET 8 (SDK target) and .NET 10 (sample target) in CI
- Added local-packages/ to .gitignore

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Use ToolDefinition/FunctionDefinition/PropertyDefinition instead of
  anonymous types (fixes CS0826)
- Use ChatCompletionCreateResponse instead of ChatCompletionResponse
  (fixes CS0234)
- Fix CompleteChatAsync argument order: (messages, tools, ct)
  (fixes CS1503)
- Add missing using for SharedModels (PropertyDefinition)
- Remove unused ProcessToolCalls method with dynamic/args conflicts

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
samuel100 and others added 2 commits March 30, 2026 13:57
- Use ::from() instead of ::new() for message construction
- Use |progress: &str| instead of |progress: f32| for download callbacks
- Use serde_json::from_value for assistant message construction
- Use ChatCompletionMessageToolCalls::Function enum pattern for tool calls
- Use foundry_local_sdk::openai::ChatClient for type annotations
- Add is_cached() check before download
- Add serde_json dependency to tutorial-chat-assistant

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- audio-transcription: foundry_local -> foundry_local_sdk, use model.get_audio_client()
- langchain-integration: foundry_local -> foundry_local_sdk, use start_web_service()
- web-server: foundry_local -> foundry_local_sdk, use start_web_service()
- Remove hello-foundry-local (legacy), add native-chat-completions (new SDK)
- Remove functioncalling (Jupyter), add tool-calling (new SDK, how-to style)
- Use qwen2.5-0.5b model alias across all samples
- Use common app_name 'foundry_local_samples' for shared model cache
- Update all 4 tutorials to use qwen2.5-0.5b and foundry_local_samples

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Use qwen2.5-0.5b for all chat samples (was phi-3.5-mini)
- Use whisper-tiny for all audio samples (was invalid 'whisper' alias)
- Use foundry_local_samples as common app_name across Python samples
- Fix tool-calling dict serialization bug in Python (ChatCompletionMessage -> dict)
- Fix /v1 URL suffix for web-server and langchain-integration Python samples

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Flatten dual windows/cross-platform csproj into single unified csproj per sample
- MSBuild IsOSPlatform condition auto-selects WinML on Windows, standard SDK elsewhere
- Move from GettingStarted/src/{Sample}/ to samples/cs/{sample-dir}/
- Each sample gets its own .sln file
- Rename HelloFoundryLocalSdk to native-chat-completions (aligns with docs)
- Remove old GettingStarted directory (windows/, cross-platform/, old .sln files)
- Update CI workflow to remove Windows/cross-platform skip logic
- Shared/Utils.cs referenced via Compile Include from 6 non-tutorial samples
- 4 tutorials get WinML support (previously cross-platform only)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mples

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…allback

All 4 languages now accept an optional audio file path as an argument
and fall back to Recording.mp3 (bundled with each sample).

- Python: changed default from audio.wav to Recording.mp3, added file
- JS: added process.argv[2] support, was hardcoded
- C#: added args[0] support, was hardcoded to base dir
- Rust: changed from required arg (exit on missing) to optional with fallback

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants