Add named regions and tutorial samples for docs externalization#563
Add named regions and tutorial samples for docs externalization#563
Conversation
- 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>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
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 tosamples/sdk/rust). Update it to point to the repo-rootsdk/rust(e.g.,../../../sdk/rust) socargo buildworks in CI.
samples/rust/tutorial-tool-calling/Cargo.toml:1 - The
foundry-local-sdkpath likely resolves tosamples/sdk/rustfrom this location. Use the correct relative path to the repo-rootsdk/rust(e.g.,../../../sdk/rust) to preventcargo buildfailures.
samples/rust/tutorial-document-summarizer/Cargo.toml:1 - This path appears to point to
samples/sdk/rustrather than the repo-rootsdk/rust. Adjust to the correct relative path (commonly../../../sdk/rustfromsamples/rust/<project>).
samples/python/tutorial-tool-calling/src/app.py:1 - This app builds
messagesas a list of dicts, butmessages.append(choice)appends an SDK message object. Mixing message types is likely to break serialization insideclient.complete_chat(...). Convertchoiceinto 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’sast-based evaluation of a restricted grammar.
samples/python/tutorial-voice-to-text/src/app.py:1 - This relies on
meeting-notes.wavbeing 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_sdkandfoundry_localimport 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" /> |
There was a problem hiding this comment.
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.
| <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="*" /> |
| <Nullable>enable</Nullable> | ||
| </PropertyGroup> | ||
| <ItemGroup> | ||
| <PackageReference Include="Microsoft.AI.Foundry.Local" Version="1.0.0" /> |
There was a problem hiding this comment.
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.
| <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" /> |
| <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" /> |
There was a problem hiding this comment.
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.
| <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="*" /> |
| <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" /> |
There was a problem hiding this comment.
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.
| <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" /> |
| const result = Function( | ||
| `"use strict"; return (${expression})` | ||
| )(); |
There was a problem hiding this comment.
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.
| const transcription = await audioClient.transcribe( | ||
| './meeting-notes.wav' | ||
| ); |
There was a problem hiding this comment.
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.
| 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 |
There was a problem hiding this comment.
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.
| 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 |
| # Install dependencies if package.json exists | ||
| $pkgJson = Join-Path $sample.DirectoryName "package.json" | ||
| if (Test-Path $pkgJson) { | ||
| Push-Location $sample.DirectoryName |
There was a problem hiding this comment.
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.
| Push-Location $sample.DirectoryName | |
| Push-Location $sample.DirectoryName | |
| npm install "foundry-local-sdk@file:$env:GITHUB_WORKSPACE/sdk/js" |
- 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>
- 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>
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.