From 0667dfc5b347fd4ab937a58e4be5443023aa803b Mon Sep 17 00:00:00 2001 From: samuel100 Date: Fri, 19 Jun 2026 17:22:18 +0100 Subject: [PATCH] init sample overhaul --- .../workflows/samples-integration-test.yml | 105 +- README.md | 19 +- docs/README.md | 17 +- samples/README.md | 62 +- samples/cpp/.gitignore | 2 + samples/cpp/README.md | 43 + samples/cpp/audio/CMakeLists.txt | 50 + samples/cpp/audio/README.md | 77 + samples/cpp/audio/Recording.wav | Bin 0 -> 527694 bytes samples/cpp/audio/main.cc | 402 +++++ samples/cpp/chat-completion/CMakeLists.txt | 24 + samples/cpp/chat-completion/README.md | 55 + samples/cpp/chat-completion/main.cc | 201 +++ samples/cpp/cmake/FoundryLocalSDK.cmake | 139 ++ samples/cpp/common/base64.h | 50 + samples/cpp/common/local_http_client.h | 268 ++++ samples/cpp/embeddings/CMakeLists.txt | 21 + samples/cpp/embeddings/README.md | 55 + samples/cpp/embeddings/main.cc | 136 ++ .../cpp/live-audio-transcription/README.md | 32 - samples/cpp/live-audio-transcription/main.cpp | 281 ---- samples/cpp/responses-api/CMakeLists.txt | 28 + samples/cpp/responses-api/README.md | 65 + samples/cpp/responses-api/main.cc | 148 ++ .../responses-api}/test_image.jpg | Bin samples/cs/Directory.Packages.props | 10 +- samples/cs/README.md | 32 +- .../AudioTranscriptionExample.sln | 34 - .../cs/audio-transcription-example/Program.cs | 87 -- .../Audio.csproj} | 20 +- .../Audio.sln} | 2 +- .../Program.cs | 75 +- samples/cs/audio/README.md | 104 ++ .../Recording.mp3 | Bin .../ChatCompletion.csproj} | 14 +- .../ChatCompletion.sln} | 2 +- .../Program.cs | 68 +- samples/cs/chat-completion/README.md | 48 + samples/cs/embeddings/Embeddings.csproj | 13 +- samples/cs/embeddings/README.md | 33 + ...oundryLocalWebServerResponsesVision.csproj | 54 - .../FoundryLocalWebServer.csproj | 39 - .../FoundryLocalWebServer.sln | 34 - .../cs/foundry-local-web-server/Program.cs | 100 -- samples/cs/live-audio-transcription/README.md | 65 - .../ModelManagementExample.csproj | 35 - .../ModelManagementExample.sln | 34 - .../cs/model-management-example/Program.cs | 155 -- .../NativeChatCompletions.csproj | 35 - samples/cs/nuget.config | 12 +- .../Program.cs | 0 samples/cs/responses-api/README.md | 46 + .../ResponsesApi.csproj} | 20 +- .../ResponsesApi.sln} | 2 +- .../responses-api}/test_image.jpg | Bin .../tool-calling-foundry-local-sdk/Program.cs | 179 --- .../ToolCallingFoundryLocalSdk.csproj | 35 - .../ToolCallingFoundryLocalSdk.sln | 34 - .../Program.cs | 190 --- .../ToolCallingFoundryLocalWebServer.sln | 34 - samples/cs/tutorial-chat-assistant/Program.cs | 114 -- .../TutorialChatAssistant.csproj | 37 - .../TutorialChatAssistant.sln | 34 - .../tutorial-document-summarizer/Program.cs | 122 -- .../TutorialDocumentSummarizer.csproj | 37 - .../TutorialDocumentSummarizer.sln | 34 - samples/cs/tutorial-tool-calling/Program.cs | 241 --- .../TutorialToolCalling.csproj | 37 - .../TutorialToolCalling.sln | 34 - samples/cs/tutorial-voice-to-text/Program.cs | 118 -- .../TutorialVoiceToText.csproj | 37 - .../TutorialVoiceToText.sln | 34 - samples/cs/verify-winml/Program.cs | 278 ---- samples/cs/verify-winml/README.md | 21 - samples/cs/verify-winml/VerifyWinML.csproj | 28 - samples/js/README.md | 29 +- samples/js/audio-transcription-example/app.js | 77 - .../audio-transcription-example/package.json | 15 - samples/js/audio/README.md | 102 ++ .../Recording.mp3 | Bin samples/js/audio/app.js | 293 ++++ .../package.json | 6 +- .../js/chat-and-audio-foundry-local/.npmrc | 2 - .../chat-and-audio-foundry-local/package.json | 15 - .../chat-and-audio-foundry-local/src/app.js | 111 -- samples/js/chat-completion/README.md | 58 + .../app.js | 68 +- .../package.json | 7 +- samples/js/copilot-sdk-foundry-local/.npmrc | 2 - .../js/copilot-sdk-foundry-local/package.json | 22 - .../js/copilot-sdk-foundry-local/src/app.ts | 155 -- .../src/tool-calling.ts | 250 --- .../foundry_local_color.svg | 40 - .../js/electron-chat-application/index.html | 174 --- samples/js/electron-chat-application/main.js | 376 ----- .../js/electron-chat-application/package.json | 21 - .../js/electron-chat-application/preload.js | 20 - .../js/electron-chat-application/renderer.js | 1066 ------------- .../electron-description-of-functions.png | Bin 554164 -> 0 bytes .../screenshots/electron-transcription.png | Bin 149700 -> 0 bytes .../js/electron-chat-application/styles.css | 1348 ----------------- samples/js/embeddings/README.md | 52 + samples/js/embeddings/package.json | 5 +- .../js/langchain-integration-example/app.js | 105 -- .../package.json | 17 - samples/js/live-audio-transcription/README.md | 58 - samples/js/live-audio-transcription/app.js | 203 --- .../js/native-chat-completions/package.json | 15 - samples/js/responses-api/README.md | 63 + .../app.js | 0 .../package.json | 4 +- .../src => js/responses-api}/test_image.jpg | Bin samples/js/tool-calling-foundry-local/.npmrc | 2 - .../tool-calling-foundry-local/package.json | 15 - .../js/tool-calling-foundry-local/src/app.js | 206 --- samples/js/tutorial-chat-assistant/app.js | 95 -- .../js/tutorial-chat-assistant/package.json | 15 - .../js/tutorial-document-summarizer/app.js | 95 -- .../tutorial-document-summarizer/package.json | 15 - samples/js/tutorial-tool-calling/app.js | 197 --- samples/js/tutorial-tool-calling/package.json | 15 - samples/js/tutorial-voice-to-text/app.js | 89 -- .../js/tutorial-voice-to-text/package.json | 15 - samples/js/verify-winml/README.md | 26 - samples/js/verify-winml/app.js | 240 --- samples/js/verify-winml/package.json | 12 - samples/js/web-server-example/app.js | 81 - samples/python/README.md | 25 +- .../audio-transcription/requirements.txt | 2 - samples/python/audio-transcription/src/app.py | 53 - samples/python/audio/README.md | 106 ++ samples/python/audio/requirements.txt | 7 + .../src}/Recording.mp3 | Bin samples/python/audio/src/app.py | 254 ++++ samples/python/chat-completion/README.md | 50 + .../python/chat-completion/requirements.txt | 5 + .../src/app.py | 48 +- samples/python/embeddings/README.md | 36 + samples/python/embeddings/requirements.txt | 5 +- .../langchain-integration/requirements.txt | 5 - .../python/langchain-integration/src/app.py | 73 - .../python/live-audio-transcription/README.md | 68 - .../live-audio-transcription/requirements.txt | 5 - .../live-audio-transcription/src/app.py | 182 --- .../native-chat-completions/requirements.txt | 2 - .../README.md | 9 +- samples/python/responses-api/requirements.txt | 5 + .../src/app.py | 0 .../responses-api/src}/test_image.jpg | Bin samples/python/tool-calling/requirements.txt | 2 - samples/python/tool-calling/src/app.py | 195 --- .../tutorial-chat-assistant/requirements.txt | 2 - .../python/tutorial-chat-assistant/src/app.py | 84 - .../requirements.txt | 2 - .../tutorial-document-summarizer/src/app.py | 91 -- .../tutorial-tool-calling/requirements.txt | 2 - .../python/tutorial-tool-calling/src/app.py | 200 --- .../tutorial-voice-to-text/requirements.txt | 2 - .../python/tutorial-voice-to-text/src/app.py | 91 -- samples/python/verify-winml/README.md | 47 - samples/python/verify-winml/requirements.txt | 1 - samples/python/verify-winml/src/app.py | 226 --- .../requirements.txt | 3 - samples/python/web-server-responses/README.md | 44 - .../web-server-responses/requirements.txt | 3 - .../python/web-server-responses/src/app.py | 152 -- samples/python/web-server/requirements.txt | 3 - samples/python/web-server/src/app.py | 73 - samples/rust/Cargo.toml | 14 +- samples/rust/README.md | 23 +- .../audio-transcription-example/Cargo.toml | 13 - .../audio-transcription-example/src/main.rs | 99 -- .../Cargo.toml | 7 +- samples/rust/audio/README.md | 28 + .../Recording.mp3 | Bin .../src/main.rs | 224 ++- .../Cargo.toml | 11 +- samples/rust/chat-completion/README.md | 17 + samples/rust/chat-completion/src/main.rs | 182 +++ samples/rust/embeddings/Cargo.toml | 3 - samples/rust/embeddings/README.md | 15 + .../rust/foundry-local-webserver/src/main.rs | 131 -- .../rust/live-audio-transcription/README.md | 21 - .../rust/native-chat-completions/Cargo.toml | 13 - .../rust/native-chat-completions/src/main.rs | 123 -- .../Cargo.toml | 5 +- samples/rust/responses-api/README.md | 21 + .../src/main.rs | 6 +- samples/rust/responses-api/test_image.jpg | Bin 0 -> 6828 bytes .../tool-calling-foundry-local/Cargo.toml | 14 - .../tool-calling-foundry-local/src/main.rs | 254 ---- .../rust/tutorial-chat-assistant/Cargo.toml | 14 - .../rust/tutorial-chat-assistant/src/main.rs | 120 -- .../tutorial-document-summarizer/Cargo.toml | 13 - .../tutorial-document-summarizer/src/main.rs | 175 --- samples/rust/tutorial-tool-calling/Cargo.toml | 14 - .../rust/tutorial-tool-calling/src/main.rs | 348 ----- .../rust/tutorial-voice-to-text/Cargo.toml | 13 - .../rust/tutorial-voice-to-text/src/main.rs | 128 -- samples/rust/verify-winml/Cargo.toml | 10 - samples/rust/verify-winml/README.md | 20 - samples/rust/verify-winml/src/main.rs | 327 ---- sdk/rust/README.md | 10 +- sdk_v2/python/README.md | 2 +- 204 files changed, 3947 insertions(+), 11662 deletions(-) create mode 100644 samples/cpp/.gitignore create mode 100644 samples/cpp/README.md create mode 100644 samples/cpp/audio/CMakeLists.txt create mode 100644 samples/cpp/audio/README.md create mode 100644 samples/cpp/audio/Recording.wav create mode 100644 samples/cpp/audio/main.cc create mode 100644 samples/cpp/chat-completion/CMakeLists.txt create mode 100644 samples/cpp/chat-completion/README.md create mode 100644 samples/cpp/chat-completion/main.cc create mode 100644 samples/cpp/cmake/FoundryLocalSDK.cmake create mode 100644 samples/cpp/common/base64.h create mode 100644 samples/cpp/common/local_http_client.h create mode 100644 samples/cpp/embeddings/CMakeLists.txt create mode 100644 samples/cpp/embeddings/README.md create mode 100644 samples/cpp/embeddings/main.cc delete mode 100644 samples/cpp/live-audio-transcription/README.md delete mode 100644 samples/cpp/live-audio-transcription/main.cpp create mode 100644 samples/cpp/responses-api/CMakeLists.txt create mode 100644 samples/cpp/responses-api/README.md create mode 100644 samples/cpp/responses-api/main.cc rename samples/{cs/foundry-local-web-server-responses-vision => cpp/responses-api}/test_image.jpg (100%) delete mode 100644 samples/cs/audio-transcription-example/AudioTranscriptionExample.sln delete mode 100644 samples/cs/audio-transcription-example/Program.cs rename samples/cs/{live-audio-transcription/LiveAudioTranscriptionExample.csproj => audio/Audio.csproj} (63%) rename samples/cs/{live-audio-transcription/LiveAudioTranscriptionExample.sln => audio/Audio.sln} (90%) rename samples/cs/{live-audio-transcription => audio}/Program.cs (68%) create mode 100644 samples/cs/audio/README.md rename samples/cs/{audio-transcription-example => audio}/Recording.mp3 (100%) rename samples/cs/{tool-calling-foundry-local-web-server/ToolCallingFoundryLocalWebServer.csproj => chat-completion/ChatCompletion.csproj} (66%) rename samples/cs/{native-chat-completions/NativeChatCompletions.sln => chat-completion/ChatCompletion.sln} (91%) rename samples/cs/{native-chat-completions => chat-completion}/Program.cs (57%) create mode 100644 samples/cs/chat-completion/README.md create mode 100644 samples/cs/embeddings/README.md delete mode 100644 samples/cs/foundry-local-web-server-responses-vision/FoundryLocalWebServerResponsesVision.csproj delete mode 100644 samples/cs/foundry-local-web-server/FoundryLocalWebServer.csproj delete mode 100644 samples/cs/foundry-local-web-server/FoundryLocalWebServer.sln delete mode 100644 samples/cs/foundry-local-web-server/Program.cs delete mode 100644 samples/cs/live-audio-transcription/README.md delete mode 100644 samples/cs/model-management-example/ModelManagementExample.csproj delete mode 100644 samples/cs/model-management-example/ModelManagementExample.sln delete mode 100644 samples/cs/model-management-example/Program.cs delete mode 100644 samples/cs/native-chat-completions/NativeChatCompletions.csproj rename samples/cs/{foundry-local-web-server-responses-vision => responses-api}/Program.cs (100%) create mode 100644 samples/cs/responses-api/README.md rename samples/cs/{audio-transcription-example/AudioTranscriptionExample.csproj => responses-api/ResponsesApi.csproj} (63%) rename samples/cs/{foundry-local-web-server-responses-vision/FoundryLocalWebServerResponsesVision.sln => responses-api/ResponsesApi.sln} (89%) rename samples/{js/web-server-responses-vision-example => cs/responses-api}/test_image.jpg (100%) delete mode 100644 samples/cs/tool-calling-foundry-local-sdk/Program.cs delete mode 100644 samples/cs/tool-calling-foundry-local-sdk/ToolCallingFoundryLocalSdk.csproj delete mode 100644 samples/cs/tool-calling-foundry-local-sdk/ToolCallingFoundryLocalSdk.sln delete mode 100644 samples/cs/tool-calling-foundry-local-web-server/Program.cs delete mode 100644 samples/cs/tool-calling-foundry-local-web-server/ToolCallingFoundryLocalWebServer.sln delete mode 100644 samples/cs/tutorial-chat-assistant/Program.cs delete mode 100644 samples/cs/tutorial-chat-assistant/TutorialChatAssistant.csproj delete mode 100644 samples/cs/tutorial-chat-assistant/TutorialChatAssistant.sln delete mode 100644 samples/cs/tutorial-document-summarizer/Program.cs delete mode 100644 samples/cs/tutorial-document-summarizer/TutorialDocumentSummarizer.csproj delete mode 100644 samples/cs/tutorial-document-summarizer/TutorialDocumentSummarizer.sln delete mode 100644 samples/cs/tutorial-tool-calling/Program.cs delete mode 100644 samples/cs/tutorial-tool-calling/TutorialToolCalling.csproj delete mode 100644 samples/cs/tutorial-tool-calling/TutorialToolCalling.sln delete mode 100644 samples/cs/tutorial-voice-to-text/Program.cs delete mode 100644 samples/cs/tutorial-voice-to-text/TutorialVoiceToText.csproj delete mode 100644 samples/cs/tutorial-voice-to-text/TutorialVoiceToText.sln delete mode 100644 samples/cs/verify-winml/Program.cs delete mode 100644 samples/cs/verify-winml/README.md delete mode 100644 samples/cs/verify-winml/VerifyWinML.csproj delete mode 100644 samples/js/audio-transcription-example/app.js delete mode 100644 samples/js/audio-transcription-example/package.json create mode 100644 samples/js/audio/README.md rename samples/js/{audio-transcription-example => audio}/Recording.mp3 (100%) create mode 100644 samples/js/audio/app.js rename samples/js/{live-audio-transcription => audio}/package.json (54%) delete mode 100644 samples/js/chat-and-audio-foundry-local/.npmrc delete mode 100644 samples/js/chat-and-audio-foundry-local/package.json delete mode 100644 samples/js/chat-and-audio-foundry-local/src/app.js create mode 100644 samples/js/chat-completion/README.md rename samples/js/{native-chat-completions => chat-completion}/app.js (60%) rename samples/js/{web-server-example => chat-completion}/package.json (53%) delete mode 100644 samples/js/copilot-sdk-foundry-local/.npmrc delete mode 100644 samples/js/copilot-sdk-foundry-local/package.json delete mode 100644 samples/js/copilot-sdk-foundry-local/src/app.ts delete mode 100644 samples/js/copilot-sdk-foundry-local/src/tool-calling.ts delete mode 100644 samples/js/electron-chat-application/foundry_local_color.svg delete mode 100644 samples/js/electron-chat-application/index.html delete mode 100644 samples/js/electron-chat-application/main.js delete mode 100644 samples/js/electron-chat-application/package.json delete mode 100644 samples/js/electron-chat-application/preload.js delete mode 100644 samples/js/electron-chat-application/renderer.js delete mode 100644 samples/js/electron-chat-application/screenshots/electron-description-of-functions.png delete mode 100644 samples/js/electron-chat-application/screenshots/electron-transcription.png delete mode 100644 samples/js/electron-chat-application/styles.css create mode 100644 samples/js/embeddings/README.md delete mode 100644 samples/js/langchain-integration-example/app.js delete mode 100644 samples/js/langchain-integration-example/package.json delete mode 100644 samples/js/live-audio-transcription/README.md delete mode 100644 samples/js/live-audio-transcription/app.js delete mode 100644 samples/js/native-chat-completions/package.json create mode 100644 samples/js/responses-api/README.md rename samples/js/{web-server-responses-vision-example => responses-api}/app.js (100%) rename samples/js/{web-server-responses-vision-example => responses-api}/package.json (62%) rename samples/{python/web-server-responses-vision/src => js/responses-api}/test_image.jpg (100%) delete mode 100644 samples/js/tool-calling-foundry-local/.npmrc delete mode 100644 samples/js/tool-calling-foundry-local/package.json delete mode 100644 samples/js/tool-calling-foundry-local/src/app.js delete mode 100644 samples/js/tutorial-chat-assistant/app.js delete mode 100644 samples/js/tutorial-chat-assistant/package.json delete mode 100644 samples/js/tutorial-document-summarizer/app.js delete mode 100644 samples/js/tutorial-document-summarizer/package.json delete mode 100644 samples/js/tutorial-tool-calling/app.js delete mode 100644 samples/js/tutorial-tool-calling/package.json delete mode 100644 samples/js/tutorial-voice-to-text/app.js delete mode 100644 samples/js/tutorial-voice-to-text/package.json delete mode 100644 samples/js/verify-winml/README.md delete mode 100644 samples/js/verify-winml/app.js delete mode 100644 samples/js/verify-winml/package.json delete mode 100644 samples/js/web-server-example/app.js delete mode 100644 samples/python/audio-transcription/requirements.txt delete mode 100644 samples/python/audio-transcription/src/app.py create mode 100644 samples/python/audio/README.md create mode 100644 samples/python/audio/requirements.txt rename samples/python/{audio-transcription => audio/src}/Recording.mp3 (100%) create mode 100644 samples/python/audio/src/app.py create mode 100644 samples/python/chat-completion/README.md create mode 100644 samples/python/chat-completion/requirements.txt rename samples/python/{native-chat-completions => chat-completion}/src/app.py (54%) create mode 100644 samples/python/embeddings/README.md delete mode 100644 samples/python/langchain-integration/requirements.txt delete mode 100644 samples/python/langchain-integration/src/app.py delete mode 100644 samples/python/live-audio-transcription/README.md delete mode 100644 samples/python/live-audio-transcription/requirements.txt delete mode 100644 samples/python/live-audio-transcription/src/app.py delete mode 100644 samples/python/native-chat-completions/requirements.txt rename samples/python/{web-server-responses-vision => responses-api}/README.md (77%) create mode 100644 samples/python/responses-api/requirements.txt rename samples/python/{web-server-responses-vision => responses-api}/src/app.py (100%) rename samples/{rust/foundry-local-webserver-responses-vision => python/responses-api/src}/test_image.jpg (100%) delete mode 100644 samples/python/tool-calling/requirements.txt delete mode 100644 samples/python/tool-calling/src/app.py delete mode 100644 samples/python/tutorial-chat-assistant/requirements.txt delete mode 100644 samples/python/tutorial-chat-assistant/src/app.py delete mode 100644 samples/python/tutorial-document-summarizer/requirements.txt delete mode 100644 samples/python/tutorial-document-summarizer/src/app.py delete mode 100644 samples/python/tutorial-tool-calling/requirements.txt delete mode 100644 samples/python/tutorial-tool-calling/src/app.py delete mode 100644 samples/python/tutorial-voice-to-text/requirements.txt delete mode 100644 samples/python/tutorial-voice-to-text/src/app.py delete mode 100644 samples/python/verify-winml/README.md delete mode 100644 samples/python/verify-winml/requirements.txt delete mode 100644 samples/python/verify-winml/src/app.py delete mode 100644 samples/python/web-server-responses-vision/requirements.txt delete mode 100644 samples/python/web-server-responses/README.md delete mode 100644 samples/python/web-server-responses/requirements.txt delete mode 100644 samples/python/web-server-responses/src/app.py delete mode 100644 samples/python/web-server/requirements.txt delete mode 100644 samples/python/web-server/src/app.py delete mode 100644 samples/rust/audio-transcription-example/Cargo.toml delete mode 100644 samples/rust/audio-transcription-example/src/main.rs rename samples/rust/{live-audio-transcription => audio}/Cargo.toml (54%) create mode 100644 samples/rust/audio/README.md rename samples/rust/{audio-transcription-example => audio}/Recording.mp3 (100%) rename samples/rust/{live-audio-transcription => audio}/src/main.rs (59%) rename samples/rust/{foundry-local-webserver => chat-completion}/Cargo.toml (50%) create mode 100644 samples/rust/chat-completion/README.md create mode 100644 samples/rust/chat-completion/src/main.rs create mode 100644 samples/rust/embeddings/README.md delete mode 100644 samples/rust/foundry-local-webserver/src/main.rs delete mode 100644 samples/rust/live-audio-transcription/README.md delete mode 100644 samples/rust/native-chat-completions/Cargo.toml delete mode 100644 samples/rust/native-chat-completions/src/main.rs rename samples/rust/{foundry-local-webserver-responses-vision => responses-api}/Cargo.toml (72%) create mode 100644 samples/rust/responses-api/README.md rename samples/rust/{foundry-local-webserver-responses-vision => responses-api}/src/main.rs (97%) create mode 100644 samples/rust/responses-api/test_image.jpg delete mode 100644 samples/rust/tool-calling-foundry-local/Cargo.toml delete mode 100644 samples/rust/tool-calling-foundry-local/src/main.rs delete mode 100644 samples/rust/tutorial-chat-assistant/Cargo.toml delete mode 100644 samples/rust/tutorial-chat-assistant/src/main.rs delete mode 100644 samples/rust/tutorial-document-summarizer/Cargo.toml delete mode 100644 samples/rust/tutorial-document-summarizer/src/main.rs delete mode 100644 samples/rust/tutorial-tool-calling/Cargo.toml delete mode 100644 samples/rust/tutorial-tool-calling/src/main.rs delete mode 100644 samples/rust/tutorial-voice-to-text/Cargo.toml delete mode 100644 samples/rust/tutorial-voice-to-text/src/main.rs delete mode 100644 samples/rust/verify-winml/Cargo.toml delete mode 100644 samples/rust/verify-winml/README.md delete mode 100644 samples/rust/verify-winml/src/main.rs diff --git a/.github/workflows/samples-integration-test.yml b/.github/workflows/samples-integration-test.yml index 7ca9192f2..9ed3f8a2e 100644 --- a/.github/workflows/samples-integration-test.yml +++ b/.github/workflows/samples-integration-test.yml @@ -36,48 +36,40 @@ jobs: with: python-version: '3.12' - - name: Configure pip for Azure Artifacts + - name: Configure pip for Azure Artifacts (ORT-Nightly feed for onnxruntime deps) run: | pip config set global.index-url https://pkgs.dev.azure.com/aiinfra/PublicPackages/_packaging/ORT-Nightly/pypi/simple/ pip config set global.extra-index-url https://pypi.org/simple/ pip config set global.pre true - - name: Build and install SDK from source - working-directory: sdk/python - shell: pwsh - run: | - python -m pip install build - echo '__version__ = "0.0.0-dev"' > src/version.py - python -m build --wheel --outdir dist/ - $wheel = (Get-ChildItem dist/*.whl | Select-Object -First 1).FullName - pip install $wheel - - - name: Install sample dependencies - shell: pwsh - run: | - Get-ChildItem samples/python/*/requirements.txt -ErrorAction SilentlyContinue | ForEach-Object { - Write-Host "Installing dependencies for $($_.Directory.Name)..." - pip install -r $_.FullName - } - - - name: Syntax check Python samples + # Samples consume the SDK from local source (tracking main) via an editable + # install declared in each sample's requirements.txt: `-e ../../../sdk/python`. + # We install from inside each sample directory so that relative path resolves. + - name: Install samples (SDK from local source) and syntax check shell: pwsh run: | $failed = @() - $samples = Get-ChildItem samples/python/*/src/app.py -ErrorAction SilentlyContinue - foreach ($sample in $samples) { - $name = $sample.Directory.Parent.Name - Write-Host "=== Checking: $name ===" - python -m py_compile $sample.FullName + $samples = Get-ChildItem samples/python -Directory -ErrorAction SilentlyContinue + foreach ($dir in $samples) { + $app = Join-Path $dir.FullName 'src/app.py' + if (-not (Test-Path $app)) { continue } + Write-Host "=== $($dir.Name) ===" + Push-Location $dir.FullName + if (Test-Path requirements.txt) { + pip install -r requirements.txt + if ($LASTEXITCODE -ne 0) { Write-Host "INSTALL FAILED: $($dir.Name)"; $failed += $dir.Name; Pop-Location; continue } + } + Pop-Location + python -m py_compile $app if ($LASTEXITCODE -ne 0) { - Write-Host "FAILED: $name" - $failed += $name + Write-Host "FAILED: $($dir.Name)" + $failed += $dir.Name } else { - Write-Host "OK: $name" + Write-Host "OK: $($dir.Name)" } } if ($failed.Count -gt 0) { - Write-Error "Failed syntax checks: $($failed -join ', ')" + Write-Error "Failed: $($failed -join ', ')" exit 1 } @@ -134,13 +126,14 @@ jobs: run: | npm install npm run build - npm link - - name: Syntax check JS samples + # Samples consume the SDK from local source (tracking main) via a + # `file:../../../sdk/js` dependency in each sample's package.json, so a plain + # `npm install` inside the sample resolves the locally built SDK (no npm link). + - name: Install and syntax check JS samples shell: pwsh run: | $failed = @() - # Find all sample app.js files (either in root or src/) $samples = @() $samples += Get-ChildItem samples/js/*/app.js -ErrorAction SilentlyContinue $samples += Get-ChildItem samples/js/*/src/app.js -ErrorAction SilentlyContinue @@ -148,12 +141,9 @@ jobs: $dir = if ($sample.Directory.Name -eq 'src') { $sample.Directory.Parent } else { $sample.Directory } $name = $dir.Name Write-Host "=== Checking: $name ===" - # Link SDK and install dependencies Push-Location $dir.FullName - npm link foundry-local-sdk 2>$null - if (Test-Path "package.json") { npm install 2>$null } + if (Test-Path "package.json") { npm install } Pop-Location - # Syntax check node --check $sample.FullName 2>&1 if ($LASTEXITCODE -ne 0) { Write-Host "FAILED: $name" @@ -188,35 +178,13 @@ jobs: 8.0.x 10.0.x - - name: Build SDK from source - shell: pwsh - run: | - # Build cross-platform SDK package - # Note: /p:TreatWarningsAsErrors=false avoids failing on SDK doc warnings - dotnet pack sdk/cs/src/Microsoft.AI.Foundry.Local.csproj ` - -o local-packages ` - /p:Version=0.9.0-dev ` - /p:IsPacking=true ` - /p:TreatWarningsAsErrors=false ` - --configuration Release - - # Build WinML SDK package (Windows only) - if ($IsWindows) { - dotnet pack sdk/cs/src/Microsoft.AI.Foundry.Local.csproj ` - -o local-packages ` - /p:Version=0.9.0-dev-20260324 ` - /p:UseWinML=true ` - /p:IsPacking=true ` - /p:TreatWarningsAsErrors=false ` - --configuration Release - } - - Write-Host "Local packages:" - Get-ChildItem local-packages/*.nupkg | ForEach-Object { Write-Host " $($_.Name)" } - - - name: Build C# samples + - name: Build C# samples (SDK via ProjectReference to sdk/cs source) shell: pwsh run: | + # Samples consume the SDK from local source (tracking main) via a + # ProjectReference to sdk/cs/src/Microsoft.AI.Foundry.Local.csproj. + # Building each sample compiles the SDK from source and restores its + # transitive Microsoft.AI.Foundry.Local.Core + third-party packages from nuget.org. $failed = @() $projects = Get-ChildItem samples/cs -Recurse -Filter "*.csproj" foreach ($proj in $projects) { @@ -282,3 +250,14 @@ jobs: - name: Clippy check working-directory: samples/rust run: cargo clippy --workspace -- -D warnings + + # ── C++ Samples ───────────────────────────────────────────────────── + # Intentionally not built here. The C++ samples consume the C++ SDK + # (sdk_v2/cpp), which is built only on dedicated build agents with vcpkg + ONNX + # Runtime provisioned (see .pipelines/) — there is no GitHub-hosted-runner recipe, + # and building it on every samples PR would be slow and flaky. The samples + # reference a *locally built* SDK unambiguously via cmake/FoundryLocalSDK.cmake, + # which fails fast with clear guidance if the SDK has not been built. Validate + # locally after `python sdk_v2/cpp/build.py`: + # cmake -S samples/cpp/ -B samples/cpp//build + # cmake --build samples/cpp//build diff --git a/README.md b/README.md index 405f45d93..9a66bb4b0 100644 --- a/README.md +++ b/README.md @@ -156,18 +156,25 @@ await whisperModel.unload(); ``` > [!TIP] -> A single `FoundryLocalManager` can manage both chat and audio models simultaneously. See the [chat-and-audio sample](samples/js/chat-and-audio-foundry-local/) for a complete example. +> A single `FoundryLocalManager` can manage both chat and audio models simultaneously. ## 📦 Samples -Explore complete working examples in the [`samples/`](samples/) folder: +Explore complete working examples in the [`samples/`](samples/) folder. These samples +track **`main`** and build the SDK from local source in this repo, so they always reflect +the latest changes: | Language | Samples | Highlights | |----------|---------|------------| -| [**C#**](samples/cs/) | 12 | Native chat, audio transcription, tool calling, model management, web server, tutorials | -| [**JavaScript**](samples/js/) | 12 | Native chat, audio, Electron app, Copilot SDK, LangChain, tool calling, tutorials | -| [**Python**](samples/python/) | 9 | Chat completions, audio transcription, LangChain, tool calling, tutorials | -| [**Rust**](samples/rust/) | 8 | Native chat, audio transcription, tool calling, web server, tutorials | +| [**C#**](samples/cs/) | 4 | Chat (native + web server), embeddings, audio (live + file), responses (vision) | +| [**JavaScript**](samples/js/) | 4 | Chat (native + web server), embeddings, audio (live + file), responses (vision) | +| [**Python**](samples/python/) | 4 | Chat (native + web server), embeddings, audio (live + file), responses (vision) | +| [**Rust**](samples/rust/) | 4 | Chat (native + web server), embeddings, audio (live + file), responses (vision) | +| [**C++**](samples/cpp/) | 4 | Chat (native + web server), embeddings, audio (live + file), responses (vision) | + +> [!TIP] +> Looking for comprehensive, version-pinned samples (used across Microsoft Learn)? See +> [microsoft-foundry/foundry-samples](https://github.com/microsoft-foundry/foundry-samples/). ## 🖥️ CLI diff --git a/docs/README.md b/docs/README.md index 5fa298a0f..b805d623e 100644 --- a/docs/README.md +++ b/docs/README.md @@ -21,9 +21,14 @@ Foundry Local is a unified local AI runtime that supports both **text generation ## Samples -- [JavaScript: Native Chat Completions](../samples/js/native-chat-completions/) — Chat completions using the native SDK API -- [JavaScript: Audio Transcription](../samples/js/audio-transcription-example/) — Speech-to-text with Whisper -- [JavaScript: Chat + Audio](../samples/js/chat-and-audio-foundry-local/) — Unified chat and audio in one app -- [JavaScript: Tool Calling](../samples/js/tool-calling-foundry-local/) — Function calling with local models -- [JavaScript: Electron Chat App](../samples/js/electron-chat-application/) — Desktop chat application -- [C#: Getting Started](../samples/cs/GettingStarted/) — C# SDK examples including audio transcription +Working examples for each language live in the [`samples/`](../samples/) folder. Each +language provides the same four samples, built from local SDK source (tracking `main`): + +- **chat-completion** — native inference plus the local OpenAI-compatible web server (`/v1/chat/completions`) +- **embeddings** — text embeddings (single and batch) +- **audio** — live microphone transcription (Nemotron) and file-based transcription (Whisper) +- **responses-api** — vision via the local web server Responses API (`/v1/responses`) + +See [`samples/README.md`](../samples/README.md) for details. For comprehensive, version-pinned +samples (used across Microsoft Learn), see +[microsoft-foundry/foundry-samples](https://github.com/microsoft-foundry/foundry-samples/). diff --git a/samples/README.md b/samples/README.md index a9d680412..3aed00308 100644 --- a/samples/README.md +++ b/samples/README.md @@ -1,15 +1,61 @@ # Foundry Local Samples -Explore complete working examples that demonstrate how to use Foundry Local — an end-to-end local AI solution that runs entirely on-device. These samples cover chat completions, embeddings, audio transcription, tool calling, LangChain integration, and more. +A small, focused set of working examples for [Foundry Local](https://learn.microsoft.com/azure/foundry-local/) — an end-to-end local AI solution that runs entirely on-device. > **New to Foundry Local?** Check out the [main README](../README.md) for an overview and quickstart, or visit the [Foundry Local documentation](https://learn.microsoft.com/azure/foundry-local/) on Microsoft Learn. +## These samples track `main` + +Every sample here **consumes the SDK from local source in this repository** and therefore +reflects the current state of `main` — they are intentionally **not pinned** to a published +package version. Concretely: + +| Language | How the SDK is consumed | Built from | +|----------|-------------------------|------------| +| **C#** | `ProjectReference` to `sdk/cs/src/Microsoft.AI.Foundry.Local.csproj` | `sdk/cs` | +| **JavaScript** | `file:` dependency on the local SDK (`foundry-local-sdk`) | `sdk/js` | +| **Python** | editable install (`-e ../../../sdk/python`) in `requirements.txt` | `sdk/python` | +| **Rust** | `path` dependency (`foundry-local-sdk = { path = "../../../sdk/rust" }`) | `sdk/rust` | +| **C++** | links the locally built `foundry_local_cpp` library | `sdk_v2/cpp` | + +> Build the relevant SDK first (see each sample's README), then build/run the sample. Because +> the samples reference local source, there is no version to bump — they always use the code +> currently checked out. + +> **What "local source" means precisely:** the Foundry Local **SDK binding** always resolves to +> the in-repo source above — never a published PyPI/npm/crates/NuGet release. Only the +> third-party **native runtime** (ONNX Runtime / GenAI / Foundry Core native) is fetched from +> public package feeds, exactly as each SDK itself obtains it. + +> **Hardware acceleration (WinML):** for simplicity and consistency, these samples use the +> standard cross-platform SDK on **all** platforms (Windows, macOS, Linux). Windows hardware +> acceleration via WinML is a capability of the SDK itself, not wired into these samples — see +> the [main README](../README.md) quickstart to enable it in your own app. + +## Want version-pinned or comprehensive samples? + +For a broader catalog of samples pinned to specific released versions — including the examples +referenced from **Microsoft Learn** content — see: + +> 👉 **[microsoft-foundry/foundry-samples](https://github.com/microsoft-foundry/foundry-samples/)** + +## What's included + +Each language provides the same four samples: + +| Sample | Description | +|--------|-------------| +| **chat** (`chat-completion`) | Runs a prompt through **native in-process inference**, then the **same prompt over the local web server** (OpenAI-compatible `/v1/chat/completions`). | +| **embeddings** (`embeddings`) | Generates text embeddings (single and batch) using the native SDK. | +| **audio** (`audio`) | **Live** microphone streaming transcription (Nemotron ASR) by default, plus **file-based** transcription (Whisper) via `--file `. | +| **responses** (`responses-api`) | Vision (image understanding) via the local web server **Responses API** (`/v1/responses`). | + ## Samples by Language -| Language | Samples | Description | -|----------|---------|-------------| -| [**C#**](cs/) | 14 | .NET SDK samples including native chat, embeddings, audio transcription, tool calling, model management, web server, vision via Responses API, tutorials, and WinML EP verification. Uses WinML on Windows for hardware acceleration. | -| [**JavaScript**](js/) | 16 | Node.js SDK samples including native chat, embeddings, audio transcription, Electron desktop app, Copilot SDK integration, LangChain, tool calling, web server, vision via Responses API, tutorials, and WinML EP verification. | -| [**Python**](python/) | 14 | Python samples using the OpenAI-compatible API, including chat, embeddings, audio transcription, LangChain integration, tool calling, web server, Responses API, tutorials, and WinML EP verification. | -| [**Rust**](rust/) | 12 | Rust SDK samples including native chat, embeddings, audio transcription, tool calling, web server, vision via Responses API, tutorials, and WinML EP verification. | -| [**C++**](cpp/) | 1 | C++ sample for live audio transcription. | +| Language | Folder | Notes | +|----------|--------|-------| +| **C#** | [`cs/`](cs/) | .NET SDK. | +| **JavaScript** | [`js/`](js/) | Node.js SDK. | +| **Python** | [`python/`](python/) | Python SDK (OpenAI-compatible API for web-server samples). | +| **Rust** | [`rust/`](rust/) | Rust SDK (Cargo workspace). | +| **C++** | [`cpp/`](cpp/) | C++ SDK (`sdk_v2/cpp`); build the SDK with `python sdk_v2/cpp/build.py` first. | diff --git a/samples/cpp/.gitignore b/samples/cpp/.gitignore new file mode 100644 index 000000000..d26e46380 --- /dev/null +++ b/samples/cpp/.gitignore @@ -0,0 +1,2 @@ +# Sample build trees +build/ diff --git a/samples/cpp/README.md b/samples/cpp/README.md new file mode 100644 index 000000000..1aa4e02f2 --- /dev/null +++ b/samples/cpp/README.md @@ -0,0 +1,43 @@ +# Foundry Local — C++ Samples + +Self-contained C++ samples for the **`sdk_v2/cpp`** SDK (the C++ rewrite, public +header `foundry_local/foundry_local_cpp.h`). + +These samples track **`main`**: they build against your **local** `sdk_v2/cpp` +build, not a pinned SDK release. + +## Build the SDK first + +Every sample links the locally-built SDK shared library, so build it once: + +```bash +python ../../sdk_v2/cpp/build.py +``` + +This produces `sdk_v2/cpp/build///` (default config +`RelWithDebInfo`). The shared `cmake/FoundryLocalSDK.cmake` module locates that +output automatically; override it with `-DFOUNDRY_LOCAL_BUILD_CONFIG=...`, +`-DFOUNDRY_LOCAL_SDK_DIR=...`, or `-DFOUNDRY_LOCAL_BUILD_DIR=...` if needed. + +## Samples + +| Sample | What it shows | +|-------------------------------------|-------------------------------------------------------------------------------| +| [`chat-completion`](chat-completion)| One chat prompt, run natively in-process **and** over the local web server (`POST /v1/chat/completions`), including streaming. | +| [`embeddings`](embeddings) | Native single and batch text embeddings. | +| [`audio`](audio) | Streaming ASR transcription from live mic (optional PortAudio) or a WAV file. | +| [`responses-api`](responses-api) | Vision / image understanding over the local web server (`POST /v1/responses`). | + +## Build and run a sample + +Each sample is standalone: + +```bash +cd chat-completion # or embeddings, audio, responses-api +cmake -S . -B build +cmake --build build +./build/ # see the sample's README for the exact target/args +``` + +Shared, header-only helpers (`common/`) and the build-wiring module (`cmake/`) are +reused across samples. diff --git a/samples/cpp/audio/CMakeLists.txt b/samples/cpp/audio/CMakeLists.txt new file mode 100644 index 000000000..b02f4ad53 --- /dev/null +++ b/samples/cpp/audio/CMakeLists.txt @@ -0,0 +1,50 @@ +# Copyright (c) Microsoft. All rights reserved. +# +# Standalone build for the Foundry Local C++ audio transcription sample. +# Build the SDK first: python ../../../sdk_v2/cpp/build.py +# Then: cmake -S . -B build && cmake --build build +# +# PortAudio is OPTIONAL: when found, live microphone capture is enabled +# (HAS_PORTAUDIO). Without it, the sample still builds and transcribes files / +# synthetic audio. + +cmake_minimum_required(VERSION 3.20) +project(foundry_local_audio_sample CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +# Locate the locally-built SDK and define the foundry_local_cpp target. +include(${CMAKE_CURRENT_LIST_DIR}/../cmake/FoundryLocalSDK.cmake) + +add_executable(audio main.cc) + +target_link_libraries(audio PRIVATE foundry_local_cpp) + +# Absolute path to this sample dir so the bundled Recording.wav is found +# regardless of where the executable runs from. +target_compile_definitions(audio PRIVATE SAMPLE_SOURCE_DIR="${CMAKE_CURRENT_LIST_DIR}") + +# --- Optional PortAudio for live microphone capture ------------------------- +find_package(PkgConfig QUIET) +if(PkgConfig_FOUND) + pkg_check_modules(PORTAUDIO QUIET portaudio-2.0) +endif() + +find_path(PORTAUDIO_INCLUDE_DIR portaudio.h + HINTS ${PORTAUDIO_INCLUDE_DIRS} /opt/homebrew/include /usr/local/include) +find_library(PORTAUDIO_LIBRARY NAMES portaudio + HINTS ${PORTAUDIO_LIBRARY_DIRS} /opt/homebrew/lib /usr/local/lib) + +if(PORTAUDIO_INCLUDE_DIR AND PORTAUDIO_LIBRARY) + message(STATUS "PortAudio found — live microphone capture enabled") + target_compile_definitions(audio PRIVATE HAS_PORTAUDIO) + target_include_directories(audio PRIVATE ${PORTAUDIO_INCLUDE_DIR}) + target_link_libraries(audio PRIVATE ${PORTAUDIO_LIBRARY}) +else() + message(STATUS "PortAudio not found — building file/synthetic-only (no live mic)") +endif() + +# Bake in the rpath so the executable finds the SDK shared library at runtime. +foundry_local_configure_sample(audio) diff --git a/samples/cpp/audio/README.md b/samples/cpp/audio/README.md new file mode 100644 index 000000000..dec0064b2 --- /dev/null +++ b/samples/cpp/audio/README.md @@ -0,0 +1,77 @@ +# Audio Transcription (C++) + +Transcribes audio with Foundry Local using two model paths — matching the +other-language `audio` samples: + +- **Live microphone → Nemotron streaming ASR** (`nemotron-speech-streaming-en-0.6b`): + incremental, real-time transcription, the same flow as + `sdk_v2/cpp/examples/realtime_audio`. +- **File → Whisper** (`whisper-tiny`): whole-file, non-streaming transcription. + +This sample tracks **`main`** — it builds against your **local** `sdk_v2/cpp` build, +not a pinned SDK release. + +## What it does + +- **Live path** uses a streaming `AudioSession`: a `Request` carries a `pcm` format + descriptor plus an `ItemQueue`, a background producer pushes PCM chunks into the + queue, and a streaming callback prints transcribed text as it arrives. +- **File path** uses a non-streaming `AudioSession`: a single `Item::AudioFromUri(path)` + drives Whisper, and the transcript is read from the response's text item. The SDK + reads and decodes the file, so no manual PCM handling is needed. + +### Modes + +| Invocation | Model | Source | +|-----------------------|----------------------|-------------------------------------------------| +| *(default)* | Nemotron (streaming) | Live microphone via PortAudio; falls back to Whisper transcription of the bundled WAV. | +| `--file [path]` | Whisper | An audio file. With no path, uses the bundled `Recording.wav`. | +| `--synth` | Nemotron (streaming) | A generated 440 Hz sine tone (no mic, no file). | + +The Nemotron streaming model expects **16 kHz mono** PCM; `Recording.wav` already +matches. + +### Live microphone is optional + +Live capture uses [PortAudio](http://www.portaudio.com/) and is enabled **only when +PortAudio is found at configure time** (the build defines `HAS_PORTAUDIO` and links +it). Without PortAudio the sample still builds and runs — the default mode falls back +to Whisper transcription of the bundled WAV, and `--file` / `--synth` work as usual. + +Install PortAudio for live mic capture: + +```bash +# macOS +brew install portaudio +# Debian/Ubuntu +sudo apt-get install portaudio19-dev +``` + +## Prerequisites + +```bash +python ../../../sdk_v2/cpp/build.py +``` + +## Build + +```bash +cmake -S . -B build +cmake --build build +``` + +Override the SDK config/location if needed: +`-DFOUNDRY_LOCAL_BUILD_CONFIG=Debug`, `-DFOUNDRY_LOCAL_SDK_DIR=...`, +`-DFOUNDRY_LOCAL_BUILD_DIR=...`. + +## Run + +```bash +./build/audio # live mic (Nemotron); falls back to Whisper file if no mic +./build/audio --file # bundled Recording.wav (Whisper) +./build/audio --file /path/to/audio.wav +./build/audio --synth # generated sine tone (Nemotron streaming) +``` + +Press `Ctrl+C` to stop live capture gracefully. + diff --git a/samples/cpp/audio/Recording.wav b/samples/cpp/audio/Recording.wav new file mode 100644 index 0000000000000000000000000000000000000000..3b0b08a94b8c5ade2cb30acd01e01dfc9fd298b4 GIT binary patch literal 527694 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 z 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 q8-69 Nemotron streaming ASR (incremental, real-time). +// * File -> Whisper (whole-file, non-streaming). +// +// The live path mirrors sdk_v2/cpp/examples/realtime_audio: a streaming AudioSession +// receives PCM through an ItemQueue and emits incremental text via a streaming +// callback. The file path submits a single AUDIO item (file URI) and reads the +// transcript from the response. +// +// Modes: +// (default) Live microphone capture via PortAudio (compile-time optional, +// behind HAS_PORTAUDIO). Falls back to Whisper transcription of the +// bundled WAV if PortAudio is unavailable. +// --file [path] Transcribe an audio file with Whisper. With no path, uses the +// bundled Recording.wav. +// --synth Stream a generated 440 Hz sine tone through the Nemotron model. +// +// The Nemotron streaming model expects 16 kHz mono PCM. + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// PortAudio is optional: the CMake build defines HAS_PORTAUDIO and links the +// library only when it is found, so the sample also builds without a mic stack. +#ifdef HAS_PORTAUDIO +#include +#endif + +using namespace foundry_local; + +namespace { + +constexpr const char* kStreamingModel = "nemotron-speech-streaming-en-0.6b"; // live mic / synthetic PCM +constexpr const char* kWhisperModel = "whisper-tiny"; // file-based transcription +constexpr int kSampleRate = 16000; +constexpr int kChannels = 1; + +// Set to false by Ctrl+C to request a graceful stop of live capture. +std::atomic g_running{true}; + +void HandleSigint(int /*signum*/) { + g_running = false; +} + +/// Resolve a catalog model by alias, download it if needed, and load it. +std::unique_ptr LoadModel(Manager& manager, const std::string& alias) { + auto model = manager.GetCatalog().GetModel(alias); + if (!model) { + throw std::runtime_error("Model '" + alias + "' not found in catalog."); + } + + std::cout << "Using model: " << model->GetInfo().Name() << "\n"; + + if (!model->IsCached()) { + std::cout << "Downloading...\n"; + model->Download([](float progress) -> int { + std::cout << "\r " << static_cast(progress) << "%" << std::flush; + return 0; // return non-zero to cancel + }); + std::cout << "\n"; + } + + if (!model->IsLoaded()) { + std::cout << "Loading model...\n"; + model->Load(); + } + + return model; +} + +/// A producer pushes PCM into the session's ItemQueue, then returns. +/// RunSession marks the queue finished once the producer returns. +using Producer = std::function; + +/// Drive an AudioSession: stream PCM from `produce` into the session and print +/// transcribed text incrementally via the streaming callback. +void RunSession(IModel& model, int sample_rate, int channels, const Producer& produce) { + AudioSession session(model); + + // The streaming callback receives one item per invocation; print TEXT items as they arrive. + session.SetStreamingCallback([](flStreamingCallbackData event) -> int { + const auto* item_api = detail::item_api(); + + flItem* raw_item = nullptr; + if (item_api->ItemQueue_TryPop(event.item_queue, &raw_item)) { + Item item(*raw_item); + if (item.GetType() == FOUNDRY_LOCAL_ITEM_TEXT) { + std::cout << item.GetText().text << std::flush; + } + } + + return 0; // return non-zero to cancel + }); + + // Queue that carries streamed audio chunks. Added to the request without + // transferring ownership so the producer thread can keep pushing into it. + ItemQueue audio_input; + + Request request; + request.AddItem(Item::AudioFromData("pcm", nullptr, 0, sample_rate, channels)); // format descriptor + request.AddItem(audio_input, /*take_ownership*/ false); + + std::thread producer([&] { + try { + produce(audio_input); + } catch (const std::exception& ex) { + std::cerr << "\nAudio producer error: " << ex.what() << "\n"; + } + + audio_input.MarkFinished(); + }); + + std::cout << "Transcription: "; + Response response = [&]() -> Response { + try { + return session.ProcessRequest(request); + } catch (...) { + // Signal + join the producer before propagating so it never outlives `audio_input`. + audio_input.MarkFinished(); + if (producer.joinable()) { + producer.join(); + } + + throw; + } + }(); + std::cout << "\n"; + + producer.join(); + + const flUsage usage = response.GetUsage(); + std::cout << "Tokens — prompt: " << usage.prompt_tokens << ", completion: " << usage.completion_tokens + << ", total: " << usage.total_tokens << "\n"; +} + +/// Produce non-owning chunks that slice a long-lived PCM buffer (file / synthetic modes). +/// `pcm` must outlive the RunSession call — BYTES items reference its storage, they do not copy. +Producer StreamBuffer(const std::vector& pcm) { + return [&pcm](ItemQueue& queue) { + constexpr size_t kChunkSize = 4096; + size_t offset = 0; + while (offset < pcm.size() && g_running) { + const size_t chunk_size = std::min(kChunkSize, pcm.size() - offset); + queue.Push(Item::Bytes(FOUNDRY_LOCAL_ITEM_BYTES, pcm.data() + offset, chunk_size)); + offset += chunk_size; + + // Pace the stream to roughly real time so the demo resembles live audio. + std::this_thread::sleep_for(std::chrono::milliseconds(125)); + } + }; +} + +/// Generate `seconds` of 16-bit mono PCM for a sine tone at `frequency_hz`. +std::vector GenerateSinePcm(int sample_rate, int seconds, double frequency_hz) { + const auto total_samples = static_cast(sample_rate) * static_cast(seconds); + std::vector pcm(total_samples * 2, 0); + for (size_t i = 0; i < total_samples; ++i) { + const double t = static_cast(i) / sample_rate; + const auto sample = static_cast(0.5 * INT16_MAX * std::sin(2.0 * M_PI * frequency_hz * t)); + const auto encoded = static_cast(sample); + pcm[i * 2] = static_cast(encoded & 0xFF); + pcm[i * 2 + 1] = static_cast((encoded >> 8) & 0xFF); + } + + return pcm; +} + +#ifdef HAS_PORTAUDIO + +/// Bounded, thread-safe queue of captured PCM chunks (drops oldest on overflow). +class CaptureQueue { + public: + void Push(std::vector chunk) { + std::lock_guard lock(mutex_); + if (queue_.size() >= kMaxSize) { + queue_.pop_front(); + } + + queue_.push_back(std::move(chunk)); + } + + bool TryPop(std::vector& out) { + std::lock_guard lock(mutex_); + if (queue_.empty()) { + return false; + } + + out = std::move(queue_.front()); + queue_.pop_front(); + return true; + } + + private: + static constexpr size_t kMaxSize = 100; + std::deque> queue_; + std::mutex mutex_; +}; + +/// PortAudio callback: copy 16-bit mono PCM into the capture queue. +int PaCapture(const void* input, void* /*output*/, unsigned long frame_count, + const PaStreamCallbackTimeInfo* /*time_info*/, PaStreamCallbackFlags /*flags*/, void* user_data) { + auto* queue = static_cast(user_data); + const auto* bytes = static_cast(input); + if (bytes != nullptr) { + const size_t byte_count = static_cast(frame_count) * 2; // 16-bit mono + queue->Push(std::vector(bytes, bytes + byte_count)); + } + + return g_running ? paContinue : paComplete; +} + +/// Producer that captures live microphone PCM and streams it into the session. +/// Returns false if the microphone could not be opened (so the caller can fall back). +bool TryRunMic(IModel& model) { + if (Pa_Initialize() != paNoError) { + return false; + } + + CaptureQueue capture; + PaStream* stream = nullptr; + + PaStreamParameters input_params{}; + input_params.device = Pa_GetDefaultInputDevice(); + if (input_params.device == paNoDevice) { + Pa_Terminate(); + return false; + } + + input_params.channelCount = kChannels; + input_params.sampleFormat = paInt16; + input_params.suggestedLatency = Pa_GetDeviceInfo(input_params.device)->defaultLowInputLatency; + input_params.hostApiSpecificStreamInfo = nullptr; + + PaError err = Pa_OpenStream(&stream, &input_params, nullptr, kSampleRate, 3200, paClipOff, PaCapture, &capture); + if (err == paNoError) { + err = Pa_StartStream(stream); + } + + if (err != paNoError) { + if (stream != nullptr) { + Pa_CloseStream(stream); + } + + Pa_Terminate(); + return false; + } + + std::cout << "\n=== LIVE TRANSCRIPTION ACTIVE — speak into your microphone (Ctrl+C to stop) ===\n"; + + // Each captured chunk is moved into an owning BYTES item: the item holds the + // buffer (via a deleter) for as long as the session needs it, so chunks can + // arrive dynamically without a single long-lived backing buffer. + RunSession(model, kSampleRate, kChannels, [&capture](ItemQueue& queue) { + while (g_running) { + std::vector chunk; + if (capture.TryPop(chunk)) { + auto* held = new std::vector(std::move(chunk)); + queue.Push(Item::Bytes(FOUNDRY_LOCAL_ITEM_BYTES, held->data(), held->size(), + [held](const flBytesData*) { delete held; })); + } else { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + } + } + }); + + Pa_StopStream(stream); + Pa_CloseStream(stream); + Pa_Terminate(); + return true; +} + +#endif // HAS_PORTAUDIO + +/// File-based transcription with the Whisper model (native, non-streaming). +/// A single AUDIO item carrying the file URI drives transcription; the SDK reads +/// and decodes the file and returns the full transcript as a TEXT item. +void RunFile(Manager& manager, const std::string& path) { + std::cout << "\n=== FILE TRANSCRIPTION (Whisper) ===\n"; + auto model = LoadModel(manager, kWhisperModel); + + AudioSession session(*model); + + Request request; + request.AddItem(Item::AudioFromUri(path)); + + std::cout << "Transcribing: " << path << "\n"; + Response response = session.ProcessRequest(request); + + std::cout << "Transcription: "; + for (const auto& item : response.GetItems()) { + if (item.GetType() == FOUNDRY_LOCAL_ITEM_TEXT) { + std::cout << item.GetText().text; + } + } + std::cout << "\n"; + + const flUsage usage = response.GetUsage(); + std::cout << "Tokens — prompt: " << usage.prompt_tokens << ", completion: " << usage.completion_tokens + << ", total: " << usage.total_tokens << "\n"; + + model->Unload(); +} + +/// Stream a generated sine tone through the Nemotron streaming model. +void RunSynth(Manager& manager) { + std::cout << "\n=== SYNTHETIC TONE (Nemotron streaming) ===\n"; + auto model = LoadModel(manager, kStreamingModel); + + std::cout << "Synthetic 440 Hz sine tone (2 s).\n"; + const std::vector pcm = GenerateSinePcm(kSampleRate, 2, 440.0); + RunSession(*model, kSampleRate, kChannels, StreamBuffer(pcm)); + + model->Unload(); +} + +struct Options { + bool use_file = false; + bool use_synth = false; + std::string file_path; +}; + +Options ParseArgs(int argc, char* argv[]) { + Options opts; + for (int i = 1; i < argc; ++i) { + const std::string arg = argv[i]; + if (arg == "--file") { + opts.use_file = true; + if (i + 1 < argc && argv[i + 1][0] != '-') { + opts.file_path = argv[++i]; + } + } else if (arg == "--synth") { + opts.use_synth = true; + } + } + + return opts; +} + +} // namespace + +int main(int argc, char* argv[]) { + const Options opts = ParseArgs(argc, argv); + const std::string bundled_wav = (std::filesystem::path(SAMPLE_SOURCE_DIR) / "Recording.wav").string(); + + std::signal(SIGINT, HandleSigint); + + try { + Configuration config("foundry_local_samples"); + Manager manager(std::move(config)); + + // Mode selection: explicit --synth / --file win; otherwise try the live mic, + // falling back to Whisper transcription of the bundled WAV. + if (opts.use_synth) { + RunSynth(manager); + } else if (opts.use_file) { + RunFile(manager, opts.file_path.empty() ? bundled_wav : opts.file_path); + } else { +#ifdef HAS_PORTAUDIO + auto model = LoadModel(manager, kStreamingModel); + const bool mic_ran = TryRunMic(*model); + model->Unload(); + + if (!mic_ran) { + std::cout << "Microphone unavailable — falling back to Whisper file transcription.\n"; + RunFile(manager, bundled_wav); + } +#else + std::cout << "Built without PortAudio — transcribing the bundled WAV with Whisper.\n"; + std::cout << "(Pass --file for another file, or --synth for a generated tone.)\n"; + RunFile(manager, bundled_wav); +#endif + } + } catch (const Error& ex) { + std::cerr << "Foundry Local error [" << ex.Code() << "]: " << ex.what() << "\n"; + return 1; + } catch (const std::exception& ex) { + std::cerr << "Error: " << ex.what() << "\n"; + return 1; + } + + return 0; +} diff --git a/samples/cpp/chat-completion/CMakeLists.txt b/samples/cpp/chat-completion/CMakeLists.txt new file mode 100644 index 000000000..b64b7221e --- /dev/null +++ b/samples/cpp/chat-completion/CMakeLists.txt @@ -0,0 +1,24 @@ +# Copyright (c) Microsoft. All rights reserved. +# +# Standalone build for the Foundry Local C++ "chat-completion" sample. +# Build the SDK first: python ../../../sdk_v2/cpp/build.py +# Then: cmake -S . -B build && cmake --build build + +cmake_minimum_required(VERSION 3.20) +project(foundry_local_chat_completion_sample CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +# Locate the locally-built SDK and define the foundry_local_cpp target. +include(${CMAKE_CURRENT_LIST_DIR}/../cmake/FoundryLocalSDK.cmake) + +add_executable(chat_completion main.cc) + +# Shared sample helpers (the minimal localhost HTTP client) live in samples/cpp/common. +target_include_directories(chat_completion PRIVATE ${CMAKE_CURRENT_LIST_DIR}/..) +target_link_libraries(chat_completion PRIVATE foundry_local_cpp) + +# Bake in the rpath so the executable finds the SDK shared library at runtime. +foundry_local_configure_sample(chat_completion) diff --git a/samples/cpp/chat-completion/README.md b/samples/cpp/chat-completion/README.md new file mode 100644 index 000000000..da27d7919 --- /dev/null +++ b/samples/cpp/chat-completion/README.md @@ -0,0 +1,55 @@ +# Chat Completion (C++) + +Runs the **same chat prompt** through the Foundry Local C++ SDK (`sdk_v2/cpp`) in +three ways so you can see the two execution surfaces side by side: + +1. **Native, in-process (non-streaming)** — `ChatSession::ProcessRequest`. +2. **Native, in-process (streaming)** — incremental tokens via a streaming callback. +3. **Local web server** — host the embedded OpenAI-compatible service with + `AddWebServiceEndpoint` + `StartWebService`, then `POST /v1/chat/completions` + over loopback using a tiny built-in HTTP client (no third-party HTTP dependency). + +The same loaded model backs all three paths — the web service reuses the model the +SDK already loaded in-process. + +This sample tracks **`main`** — it builds against your **local** `sdk_v2/cpp` build, +not a pinned SDK release. + +## What it does + +1. Creates a `Manager` with an embedded web service endpoint + (`http://127.0.0.1:0` — an ephemeral port chosen by the OS). +2. Resolves the `qwen2.5-0.5b` chat model, downloading + loading it if needed. +3. Runs the prompt natively (non-streaming, then streaming). +4. Starts the web service, discovers the bound URL via `GetWebServiceEndpoints()`, + and POSTs the same prompt to `/v1/chat/completions` (the request body is built + from typed structs serialized with `nlohmann/json`). + +> The web service resolves models by their full **variant id** (e.g. +> `qwen2.5-0.5b-instruct-generic-cpu`), which the sample reads from +> `ModelInfo::Id()` — not the short alias. + +## Prerequisites + +```bash +python ../../../sdk_v2/cpp/build.py +``` + +## Build + +```bash +cmake -S . -B build +cmake --build build +``` + +Override the SDK config/location if needed: +`-DFOUNDRY_LOCAL_BUILD_CONFIG=Debug`, `-DFOUNDRY_LOCAL_SDK_DIR=...`, +`-DFOUNDRY_LOCAL_BUILD_DIR=...`. + +## Run + +```bash +./build/chat_completion # Windows: .\build\chat_completion.exe +``` + +The first run downloads the model; later runs use the cache. diff --git a/samples/cpp/chat-completion/main.cc b/samples/cpp/chat-completion/main.cc new file mode 100644 index 000000000..97efaf9b8 --- /dev/null +++ b/samples/cpp/chat-completion/main.cc @@ -0,0 +1,201 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Sample: Chat completions with the Foundry Local C++ SDK (sdk_v2/cpp), shown two +// ways with the *same* prompt so you can compare them: +// +// 1. Native, in-process inference via ChatSession (non-streaming + streaming). +// 2. The embedded OpenAI-compatible web service: host it with +// AddWebServiceEndpoint + StartWebService, then POST /v1/chat/completions. +// +// Both paths use the same loaded model — the web service reuses the in-process +// model the SDK already loaded. + +#include + +#include + +#include +#include +#include + +#include "common/local_http_client.h" + +using namespace foundry_local; +using json = nlohmann::json; + +namespace { + +constexpr const char* kModelAlias = "qwen2.5-0.5b"; +constexpr const char* kPrompt = "What is the capital of France?"; + +// --------------------------------------------------------------------------- +// JSON contract types for POST /v1/chat/completions (OpenAI shape). +// --------------------------------------------------------------------------- + +struct ChatMessage { + std::string role; + std::string content; +}; + +struct ChatCompletionRequest { + std::string model; + std::vector messages; + bool stream = false; +}; + +void to_json(json& j, const ChatMessage& m) { + j = json{{"role", m.role}, {"content", m.content}}; +} + +void to_json(json& j, const ChatCompletionRequest& r) { + j = json{{"model", r.model}, {"messages", r.messages}, {"stream", r.stream}}; +} + +// --------------------------------------------------------------------------- +// Native, in-process inference. +// --------------------------------------------------------------------------- + +void NativeNonStreaming(IModel& model) { + ChatSession session(model); + + Request request{UserMessage(kPrompt)}; + Response response = session.ProcessRequest(request); + + for (const auto& item : response.GetItems()) { + if (item.GetType() == FOUNDRY_LOCAL_ITEM_MESSAGE) { + std::cout << "Assistant: " << item.GetMessage().GetSimpleText() << "\n"; + } + } + + const flUsage usage = response.GetUsage(); + std::cout << "Tokens — prompt: " << usage.prompt_tokens << ", completion: " << usage.completion_tokens + << ", total: " << usage.total_tokens << "\n"; +} + +void NativeStreaming(IModel& model) { + ChatSession session(model); + + // Each callback delivers exactly one item from the queue; we print TEXT items as they arrive. + session.SetStreamingCallback([](flStreamingCallbackData event) -> int { + const auto* item_api = detail::item_api(); + + flItem* raw_item = nullptr; + if (item_api->ItemQueue_TryPop(event.item_queue, &raw_item)) { + Item item(*raw_item); + if (item.GetType() == FOUNDRY_LOCAL_ITEM_TEXT) { + std::cout << item.GetText().text << std::flush; + } + } + + return 0; // return non-zero to cancel + }); + + Request request{UserMessage(kPrompt)}; + + std::cout << "Assistant: "; + session.ProcessRequest(request); + std::cout << "\n"; +} + +// --------------------------------------------------------------------------- +// Web service inference: POST the same prompt to /v1/chat/completions. +// --------------------------------------------------------------------------- + +void WebServiceChat(Manager& manager, IModel& model) { + manager.StartWebService(); + + const std::vector endpoints = manager.GetWebServiceEndpoints(); + if (endpoints.empty()) { + std::cerr << "Web service did not report any endpoints.\n"; + return; + } + + const sample::http::Url url = sample::http::ParseUrl(endpoints[0]); + std::cout << "Web service listening at " << endpoints[0] << "\n"; + + // The web service resolves models by their full variant id, not the alias. + ChatCompletionRequest request{.model = std::string(model.GetInfo().Id()), + .messages = {{"user", kPrompt}}, + .stream = false}; + + const json body = request; + const sample::http::Response response = + sample::http::Post(url.host, url.port, "/v1/chat/completions", body.dump()); + + if (response.status != 200) { + std::cerr << "HTTP " << response.status << ": " << response.body << "\n"; + manager.StopWebService(); + return; + } + + const json parsed = json::parse(response.body); + const std::string content = parsed["choices"][0]["message"].value("content", ""); + std::cout << "Assistant: " << content << "\n"; + + if (parsed.contains("usage")) { + const auto& usage = parsed["usage"]; + std::cout << "Tokens — prompt: " << usage.value("prompt_tokens", 0) + << ", completion: " << usage.value("completion_tokens", 0) + << ", total: " << usage.value("total_tokens", 0) << "\n"; + } + + manager.StopWebService(); +} + +} // namespace + +int main() { + try { + // 1. Configure the SDK and request an embedded web service endpoint + // (ephemeral port — the bound URL is reported by GetWebServiceEndpoints()). + Configuration config("foundry_local_samples"); + config.AddWebServiceEndpoint("http://127.0.0.1:0"); + + Manager manager(std::move(config)); + + // 2. Resolve the chat model and prepare it. + auto& catalog = manager.GetCatalog(); + auto model = catalog.GetModel(kModelAlias); + if (!model) { + std::cerr << "Model '" << kModelAlias << "' not found in catalog.\n"; + return 1; + } + + std::cout << "Using model: " << model->GetInfo().Name() << "\n"; + + if (!model->IsCached()) { + std::cout << "Downloading...\n"; + model->Download([](float progress) -> int { + std::cout << "\r " << static_cast(progress) << "%" << std::flush; + return 0; // return non-zero to cancel + }); + std::cout << "\n"; + } + + if (!model->IsLoaded()) { + std::cout << "Loading model...\n"; + model->Load(); + } + + // 3. Run the same prompt three ways. + std::cout << "\n=== Native in-process (non-streaming) ===\n"; + NativeNonStreaming(*model); + + std::cout << "\n=== Native in-process (streaming) ===\n"; + NativeStreaming(*model); + + std::cout << "\n=== Local web server (POST /v1/chat/completions) ===\n"; + WebServiceChat(manager, *model); + + model->Unload(); + } catch (const Error& ex) { + std::cerr << "Foundry Local error [" << ex.Code() << "]: " << ex.what() << "\n"; + return 1; + } catch (const std::exception& ex) { + std::cerr << "Error: " << ex.what() << "\n"; + return 1; + } + + return 0; +} diff --git a/samples/cpp/cmake/FoundryLocalSDK.cmake b/samples/cpp/cmake/FoundryLocalSDK.cmake new file mode 100644 index 000000000..5cb70dcef --- /dev/null +++ b/samples/cpp/cmake/FoundryLocalSDK.cmake @@ -0,0 +1,139 @@ +# Copyright (c) Microsoft. All rights reserved. +# +# FoundryLocalSDK.cmake — wires a sample against a *locally built* copy of the +# Foundry Local C++ SDK (sdk_v2/cpp). +# +# The SDK does not install/export a CMake package, and re-building it via +# add_subdirectory() would require the full vcpkg toolchain. Instead, after a +# user runs `python sdk_v2/cpp/build.py`, this module references that build tree +# directly: it picks up the public headers from sdk_v2/cpp/include, the bundled +# third-party headers vcpkg produced (gsl/span — required by the C++ wrapper — +# and nlohmann/json, used by the web-service samples), and the built shared +# library. It then defines an INTERFACE target `foundry_local_cpp` so each +# sample links it exactly like the in-tree SDK examples do. +# +# Override points (cache variables): +# FOUNDRY_LOCAL_SDK_DIR Path to sdk_v2/cpp (default: repo layout) +# FOUNDRY_LOCAL_BUILD_CONFIG SDK build config (default: RelWithDebInfo) +# FOUNDRY_LOCAL_BUILD_DIR SDK build output dir (default: derived) + +if(TARGET foundry_local_cpp) + return() +endif() + +# --- Locate the SDK source tree --------------------------------------------- +get_filename_component(_fl_default_sdk_dir "${CMAKE_CURRENT_LIST_DIR}/../../../sdk_v2/cpp" ABSOLUTE) +set(FOUNDRY_LOCAL_SDK_DIR "${_fl_default_sdk_dir}" CACHE PATH "Path to the sdk_v2/cpp source tree") + +set(_fl_include_dir "${FOUNDRY_LOCAL_SDK_DIR}/include") +if(NOT EXISTS "${_fl_include_dir}/foundry_local/foundry_local_cpp.h") + message(FATAL_ERROR + "Foundry Local public header not found under '${_fl_include_dir}'.\n" + "Set -DFOUNDRY_LOCAL_SDK_DIR=/sdk_v2/cpp.") +endif() + +# --- Derive the build output directory (mirrors build.py's layout) ---------- +# build.py writes to build//. +if(WIN32) + set(_fl_platform "Windows") +elseif(APPLE) + set(_fl_platform "macOS") +else() + set(_fl_platform "Linux") +endif() + +set(FOUNDRY_LOCAL_BUILD_CONFIG "RelWithDebInfo" + CACHE STRING "SDK build configuration produced by build.py (Debug/Release/RelWithDebInfo/MinSizeRel)") +set(FOUNDRY_LOCAL_BUILD_DIR "${FOUNDRY_LOCAL_SDK_DIR}/build/${_fl_platform}/${FOUNDRY_LOCAL_BUILD_CONFIG}" + CACHE PATH "SDK build output directory") + +if(NOT EXISTS "${FOUNDRY_LOCAL_BUILD_DIR}") + message(FATAL_ERROR + "SDK build directory '${FOUNDRY_LOCAL_BUILD_DIR}' does not exist.\n" + "Build the SDK first: python ${FOUNDRY_LOCAL_SDK_DIR}/build.py --config ${FOUNDRY_LOCAL_BUILD_CONFIG}\n" + "Or point -DFOUNDRY_LOCAL_BUILD_DIR=.") +endif() + +# --- Bundled third-party headers (gsl, nlohmann/json) ----------------------- +# The C++ wrapper includes , so every TU that includes it needs the +# GSL headers. vcpkg dropped them under build/.../vcpkg_installed//include. +file(GLOB _fl_vcpkg_includes "${FOUNDRY_LOCAL_BUILD_DIR}/vcpkg_installed/*/include") +set(_fl_thirdparty_include "") +foreach(_inc ${_fl_vcpkg_includes}) + if(EXISTS "${_inc}/gsl/span") + set(_fl_thirdparty_include "${_inc}") + break() + endif() +endforeach() + +if(_fl_thirdparty_include STREQUAL "") + message(FATAL_ERROR + "Could not find the bundled GSL headers (gsl/span) under " + "'${FOUNDRY_LOCAL_BUILD_DIR}/vcpkg_installed/*/include'.\n" + "Re-run the SDK build: python ${FOUNDRY_LOCAL_SDK_DIR}/build.py") +endif() + +# --- Locate the shared library ---------------------------------------------- +# Unix single-config: build/.../bin. Windows multi-config: build/.../bin/. +set(_fl_bin_candidates + "${FOUNDRY_LOCAL_BUILD_DIR}/bin" + "${FOUNDRY_LOCAL_BUILD_DIR}/bin/${FOUNDRY_LOCAL_BUILD_CONFIG}") + +find_library(FOUNDRY_LOCAL_LINK_LIB + NAMES foundry_local + PATHS ${_fl_bin_candidates} "${FOUNDRY_LOCAL_BUILD_DIR}/${FOUNDRY_LOCAL_BUILD_CONFIG}" + NO_DEFAULT_PATH) + +if(NOT FOUNDRY_LOCAL_LINK_LIB) + message(FATAL_ERROR + "Could not find the foundry_local library under '${FOUNDRY_LOCAL_BUILD_DIR}'.\n" + "Build the SDK first: python ${FOUNDRY_LOCAL_SDK_DIR}/build.py --config ${FOUNDRY_LOCAL_BUILD_CONFIG}") +endif() + +# Runtime directory that holds the shared library + co-located ORT/GenAI libs. +# On Windows the import .lib may sit elsewhere, so locate the .dll explicitly. +if(WIN32) + find_file(FOUNDRY_LOCAL_DLL + NAMES foundry_local.dll + PATHS ${_fl_bin_candidates} + NO_DEFAULT_PATH) + if(FOUNDRY_LOCAL_DLL) + get_filename_component(FOUNDRY_LOCAL_BIN_DIR "${FOUNDRY_LOCAL_DLL}" DIRECTORY) + else() + set(FOUNDRY_LOCAL_BIN_DIR "${FOUNDRY_LOCAL_BUILD_DIR}/bin/${FOUNDRY_LOCAL_BUILD_CONFIG}") + endif() +else() + get_filename_component(FOUNDRY_LOCAL_BIN_DIR "${FOUNDRY_LOCAL_LINK_LIB}" DIRECTORY) +endif() + +# --- The consumable INTERFACE target ---------------------------------------- +add_library(foundry_local_cpp INTERFACE) +target_include_directories(foundry_local_cpp INTERFACE + "${_fl_include_dir}" + "${_fl_thirdparty_include}") +target_link_libraries(foundry_local_cpp INTERFACE "${FOUNDRY_LOCAL_LINK_LIB}") +target_compile_features(foundry_local_cpp INTERFACE cxx_std_20) + +message(STATUS "Foundry Local SDK library: ${FOUNDRY_LOCAL_LINK_LIB}") +message(STATUS "Foundry Local SDK headers: ${_fl_include_dir}") + +# --- Per-target finalizer: make the executable find the shared lib at runtime. +# The shared library bakes in @loader_path/$ORIGIN, so co-located ORT/GenAI libs +# resolve automatically once the executable can find libfoundry_local itself. +function(foundry_local_configure_sample _target) + if(APPLE) + set_target_properties(${_target} PROPERTIES BUILD_RPATH "${FOUNDRY_LOCAL_BIN_DIR}") + elseif(UNIX) + # --disable-new-dtags forces RPATH (not RUNPATH) so it propagates to GenAI's + # internal dlopen("libonnxruntime.so") — same treatment as the SDK examples. + set_target_properties(${_target} PROPERTIES BUILD_RPATH "${FOUNDRY_LOCAL_BIN_DIR}") + target_link_options(${_target} PRIVATE -Wl,--disable-new-dtags) + elseif(WIN32) + # Windows has no rpath: copy every runtime DLL next to the executable. + file(GLOB _fl_runtime_dlls "${FOUNDRY_LOCAL_BIN_DIR}/*.dll") + foreach(_dll ${_fl_runtime_dlls}) + add_custom_command(TARGET ${_target} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different "${_dll}" "$") + endforeach() + endif() +endfunction() diff --git a/samples/cpp/common/base64.h b/samples/cpp/common/base64.h new file mode 100644 index 000000000..c59b1d1d2 --- /dev/null +++ b/samples/cpp/common/base64.h @@ -0,0 +1,50 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Minimal standard Base64 encoder used to embed image bytes in a Responses API +// `data:` URL. Header-only and dependency-free. + +#pragma once + +#include +#include +#include + +namespace sample { + +/// Encode raw bytes as standard (RFC 4648) Base64 with '=' padding. +inline std::string Base64Encode(const uint8_t* data, size_t size) { + static constexpr char kChars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + std::string out; + out.reserve(((size + 2) / 3) * 4); + + size_t i = 0; + while (i < size) { + const uint32_t octet_a = i < size ? data[i++] : 0; + const uint32_t octet_b = i < size ? data[i++] : 0; + const uint32_t octet_c = i < size ? data[i++] : 0; + const uint32_t triple = (octet_a << 16) | (octet_b << 8) | octet_c; + + out.push_back(kChars[(triple >> 18) & 0x3F]); + out.push_back(kChars[(triple >> 12) & 0x3F]); + out.push_back(kChars[(triple >> 6) & 0x3F]); + out.push_back(kChars[triple & 0x3F]); + } + + // Apply '=' padding for the trailing partial group. + if (const size_t mod = size % 3; mod == 1) { + out[out.size() - 2] = '='; + out[out.size() - 1] = '='; + } else if (mod == 2) { + out[out.size() - 1] = '='; + } + + return out; +} + +inline std::string Base64Encode(const std::vector& data) { + return Base64Encode(data.data(), data.size()); +} + +} // namespace sample diff --git a/samples/cpp/common/local_http_client.h b/samples/cpp/common/local_http_client.h new file mode 100644 index 000000000..2e2a5decc --- /dev/null +++ b/samples/cpp/common/local_http_client.h @@ -0,0 +1,268 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Minimal, dependency-free HTTP/1.1 client for talking to the Foundry Local +// embedded web service on localhost. It is intentionally tiny: a single blocking +// POST that returns the full response. The Foundry Local web service is reached +// over loopback, so we don't need TLS, redirects, proxies, or keep-alive — we +// send `Connection: close` and read the body until the server closes the socket. +// +// Header-only so every sample can include it without extra build wiring. + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#ifdef _WIN32 +#include +#include +#pragma comment(lib, "ws2_32.lib") +#else +#include +#include +#include +#include +#endif + +namespace sample::http { + +/// Parsed components of an "http://host:port/path" URL. +struct Url { + std::string host; + std::string port = "80"; + std::string path = "/"; +}; + +/// Parse "http://127.0.0.1:5273/v1" into {host, port, path}. Only the http scheme is supported. +inline Url ParseUrl(const std::string& url) { + std::string rest = url; + + if (const auto scheme = rest.find("://"); scheme != std::string::npos) { + rest = rest.substr(scheme + 3); + } + + Url out; + std::string host_port = rest; + if (const auto slash = rest.find('/'); slash != std::string::npos) { + host_port = rest.substr(0, slash); + out.path = rest.substr(slash); + } + + out.host = host_port; + if (const auto colon = host_port.rfind(':'); colon != std::string::npos) { + out.host = host_port.substr(0, colon); + out.port = host_port.substr(colon + 1); + } + + return out; +} + +/// Result of an HTTP request: numeric status code and the raw response body. +struct Response { + int status = 0; + std::string body; +}; + +namespace detail { + +#ifdef _WIN32 +using socket_t = SOCKET; +constexpr socket_t kInvalidSocket = INVALID_SOCKET; + +inline void CloseSocket(socket_t s) { ::closesocket(s); } + +/// Initialize Winsock once per process via a function-local static. +inline void EnsureWinsock() { + static const bool ok = [] { + WSADATA data; + return ::WSAStartup(MAKEWORD(2, 2), &data) == 0; + }(); + + if (!ok) { + throw std::runtime_error("WSAStartup failed"); + } +} +#else +using socket_t = int; +constexpr socket_t kInvalidSocket = -1; + +inline void CloseSocket(socket_t s) { ::close(s); } +inline void EnsureWinsock() {} +#endif + +/// RAII wrapper so the socket is always closed, even on exceptions. +class Socket { + public: + explicit Socket(socket_t fd) : fd_(fd) {} + ~Socket() { + if (fd_ != kInvalidSocket) { + CloseSocket(fd_); + } + } + + Socket(const Socket&) = delete; + Socket& operator=(const Socket&) = delete; + + socket_t get() const noexcept { return fd_; } + + private: + socket_t fd_; +}; + +/// Open a TCP connection to host:port, returning a connected socket. +inline socket_t Connect(const std::string& host, const std::string& port) { + EnsureWinsock(); + + addrinfo hints{}; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + addrinfo* result = nullptr; + if (::getaddrinfo(host.c_str(), port.c_str(), &hints, &result) != 0 || result == nullptr) { + throw std::runtime_error("Failed to resolve " + host + ":" + port); + } + + socket_t fd = kInvalidSocket; + for (addrinfo* ai = result; ai != nullptr; ai = ai->ai_next) { + fd = ::socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); + if (fd == kInvalidSocket) { + continue; + } + + if (::connect(fd, ai->ai_addr, static_cast(ai->ai_addrlen)) == 0) { + break; + } + + CloseSocket(fd); + fd = kInvalidSocket; + } + + ::freeaddrinfo(result); + + if (fd == kInvalidSocket) { + throw std::runtime_error("Failed to connect to " + host + ":" + port); + } + + return fd; +} + +/// Send the entire buffer, looping until every byte is written. +inline void SendAll(socket_t fd, const std::string& data) { + size_t sent = 0; + while (sent < data.size()) { + const auto n = ::send(fd, data.data() + sent, static_cast(data.size() - sent), 0); + if (n <= 0) { + throw std::runtime_error("Socket send failed"); + } + + sent += static_cast(n); + } +} + +/// Read the full response until the peer closes the connection. +inline std::string ReadAll(socket_t fd) { + std::string out; + char buffer[8192]; + while (true) { + const auto n = ::recv(fd, buffer, sizeof(buffer), 0); + if (n < 0) { + throw std::runtime_error("Socket recv failed"); + } + + if (n == 0) { + break; // peer closed + } + + out.append(buffer, static_cast(n)); + } + + return out; +} + +/// Split a raw HTTP response into status code + body, decoding chunked bodies. +inline Response ParseHttpResponse(const std::string& raw) { + Response resp; + + const auto header_end = raw.find("\r\n\r\n"); + if (header_end == std::string::npos) { + throw std::runtime_error("Malformed HTTP response (no header terminator)"); + } + + const std::string headers = raw.substr(0, header_end); + std::string body = raw.substr(header_end + 4); + + // Status line: "HTTP/1.1 200 OK" + if (const auto sp = headers.find(' '); sp != std::string::npos) { + resp.status = std::atoi(headers.c_str() + sp + 1); + } + + // Decode Transfer-Encoding: chunked if present (the web service uses it for some responses). + std::string lower_headers = headers; + for (char& c : lower_headers) { + c = static_cast(std::tolower(static_cast(c))); + } + + if (lower_headers.find("transfer-encoding: chunked") != std::string::npos) { + std::string decoded; + size_t pos = 0; + while (pos < body.size()) { + const auto line_end = body.find("\r\n", pos); + if (line_end == std::string::npos) { + break; + } + + const size_t chunk_size = std::strtoul(body.substr(pos, line_end - pos).c_str(), nullptr, 16); + if (chunk_size == 0) { + break; + } + + const size_t data_start = line_end + 2; + if (data_start + chunk_size > body.size()) { + break; + } + + decoded.append(body, data_start, chunk_size); + pos = data_start + chunk_size + 2; // skip chunk data + trailing CRLF + } + + body = std::move(decoded); + } + + resp.body = std::move(body); + return resp; +} + +} // namespace detail + +/// POST a body to host:port/path and return the full response. +/// `extra_headers` entries are sent verbatim (e.g. {"Accept: application/json"}). +inline Response Post(const std::string& host, const std::string& port, const std::string& path, + const std::string& body, const std::string& content_type = "application/json", + const std::vector& extra_headers = {}) { + detail::Socket sock(detail::Connect(host, port)); + + std::string request; + request += "POST " + path + " HTTP/1.1\r\n"; + request += "Host: " + host + ":" + port + "\r\n"; + request += "Content-Type: " + content_type + "\r\n"; + request += "Content-Length: " + std::to_string(body.size()) + "\r\n"; + request += "Connection: close\r\n"; + for (const auto& header : extra_headers) { + request += header + "\r\n"; + } + + request += "\r\n"; + request += body; + + detail::SendAll(sock.get(), request); + + return detail::ParseHttpResponse(detail::ReadAll(sock.get())); +} + +} // namespace sample::http diff --git a/samples/cpp/embeddings/CMakeLists.txt b/samples/cpp/embeddings/CMakeLists.txt new file mode 100644 index 000000000..8c2618358 --- /dev/null +++ b/samples/cpp/embeddings/CMakeLists.txt @@ -0,0 +1,21 @@ +# Copyright (c) Microsoft. All rights reserved. +# +# Standalone build for the Foundry Local C++ "embeddings" sample. +# Build the SDK first: python ../../../sdk_v2/cpp/build.py +# Then: cmake -S . -B build && cmake --build build + +cmake_minimum_required(VERSION 3.20) +project(foundry_local_embeddings_sample CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +# Locate the locally-built SDK and define the foundry_local_cpp target. +include(${CMAKE_CURRENT_LIST_DIR}/../cmake/FoundryLocalSDK.cmake) + +add_executable(embeddings main.cc) +target_link_libraries(embeddings PRIVATE foundry_local_cpp) + +# Bake in the rpath so the executable finds the SDK shared library at runtime. +foundry_local_configure_sample(embeddings) diff --git a/samples/cpp/embeddings/README.md b/samples/cpp/embeddings/README.md new file mode 100644 index 000000000..12462139b --- /dev/null +++ b/samples/cpp/embeddings/README.md @@ -0,0 +1,55 @@ +# Embeddings (C++) + +Generates text embeddings **natively, in-process** with the Foundry Local C++ SDK +(`sdk_v2/cpp`) — no web server involved. It embeds a single sentence, then a batch +of sentences, and prints the cosine similarity between every pair so you can see +that semantically related sentences score higher. + +This sample tracks **`main`** — it builds against your **local** `sdk_v2/cpp` build, +not a pinned SDK release. + +## What it does + +1. Creates a `Manager` and finds the first `embeddings` model in the catalog + (e.g. `qwen3-embedding-0.6b`). +2. Downloads the model if it isn't cached, then loads it. +3. Uses an `EmbeddingsSession` to: + - embed a single string and print its dimensionality + first few values; + - embed a batch of strings and print pairwise cosine similarities. + +## Prerequisites + +Build the SDK once so the shared library and headers exist: + +```bash +python ../../../sdk_v2/cpp/build.py +``` + +This produces `sdk_v2/cpp/build//RelWithDebInfo/`, which the +sample's CMake locates automatically. + +## Build + +```bash +cmake -S . -B build +cmake --build build +``` + +If you built the SDK with a different configuration, pass it through: + +```bash +cmake -S . -B build -DFOUNDRY_LOCAL_BUILD_CONFIG=Debug +``` + +You can also point at a non-default SDK location with +`-DFOUNDRY_LOCAL_SDK_DIR=/sdk_v2/cpp` or +`-DFOUNDRY_LOCAL_BUILD_DIR=`. + +## Run + +```bash +./build/embeddings # Windows: .\build\embeddings.exe +``` + +The first run downloads the embeddings model (a few hundred MB); subsequent runs +use the cache. diff --git a/samples/cpp/embeddings/main.cc b/samples/cpp/embeddings/main.cc new file mode 100644 index 000000000..c4d5bdc02 --- /dev/null +++ b/samples/cpp/embeddings/main.cc @@ -0,0 +1,136 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Sample: Text embeddings with the Foundry Local C++ SDK (sdk_v2/cpp). +// Demonstrates native, in-process embedding generation for a single input and a +// batch, then computes cosine similarity between the batch vectors. + +#include + +#include +#include +#include +#include + +using namespace foundry_local; + +namespace { + +/// Cosine similarity between two equal-length vectors. Returns 0 if either is a zero vector. +float CosineSimilarity(const std::vector& a, const std::vector& b) { + float dot = 0.0f; + float norm_a = 0.0f; + float norm_b = 0.0f; + for (size_t i = 0; i < a.size() && i < b.size(); ++i) { + dot += a[i] * b[i]; + norm_a += a[i] * a[i]; + norm_b += b[i] * b[i]; + } + + if (norm_a == 0.0f || norm_b == 0.0f) { + return 0.0f; + } + + return dot / (std::sqrt(norm_a) * std::sqrt(norm_b)); +} + +/// Find the first embeddings model in the catalog and return its alias, or "" if none exist. +std::string FindEmbeddingsAlias(ICatalog& catalog) { + ModelList all_models = catalog.GetModels(); + for (const auto& model : all_models.Models()) { + if (model->GetInfo().Task() == "embeddings") { + return std::string(model->GetInfo().Alias()); + } + } + + return ""; +} + +} // namespace + +int main() { + try { + // 1. Create a configuration and manager (long-lived; keep it alive while using the SDK). + Configuration config("foundry_local_samples"); + Manager manager(std::move(config)); + + // 2. Locate an embeddings model in the catalog. + auto& catalog = manager.GetCatalog(); + const std::string alias = FindEmbeddingsAlias(catalog); + if (alias.empty()) { + std::cerr << "No embeddings model found in the catalog.\n"; + return 1; + } + + auto model = catalog.GetModel(alias); + if (!model) { + std::cerr << "Failed to retrieve embeddings model '" << alias << "'.\n"; + return 1; + } + + ModelInfo info = model->GetInfo(); + std::cout << "Using model: " << info.Name() << " (alias: " << info.Alias() << ")\n"; + + // 3. Download if not already cached. + if (!model->IsCached()) { + std::cout << "Downloading...\n"; + model->Download([](float progress) -> int { + std::cout << "\r " << static_cast(progress) << "%" << std::flush; + return 0; // return non-zero to cancel + }); + std::cout << "\n"; + } + + // 4. Load the model into memory. + if (!model->IsLoaded()) { + std::cout << "Loading model...\n"; + model->Load(); + } + + // 5. Create an embeddings session and generate vectors. + { + EmbeddingsSession session(*model); + + std::cout << "\n=== Single embedding ===\n"; + std::vector embedding = session.Embed("The quick brown fox jumps over the lazy dog."); + std::cout << "Dimensions: " << embedding.size() << "\n"; + std::cout << "First 5 values: ["; + for (size_t i = 0; i < 5 && i < embedding.size(); ++i) { + std::cout << (i > 0 ? ", " : "") << embedding[i]; + } + std::cout << "]\n"; + + std::cout << "\n=== Batch embeddings + cosine similarity ===\n"; + const std::vector sentences = { + "The cat sat on the mat.", + "A kitten rested on the rug.", + "The stock market crashed yesterday.", + }; + + std::vector> embeddings = session.Embed(sentences); + if (embeddings.empty()) { + std::cerr << "No embeddings returned for the batch input.\n"; + return 1; + } + + std::cout << "Generated " << embeddings.size() << " embeddings of dimension " << embeddings[0].size() << "\n\n"; + + // Compare every pair: semantically similar sentences should score higher. + for (size_t i = 0; i < sentences.size(); ++i) { + for (size_t j = i + 1; j < sentences.size(); ++j) { + const float similarity = CosineSimilarity(embeddings[i], embeddings[j]); + std::cout << " similarity(\"" << sentences[i] << "\",\n" + << " \"" << sentences[j] << "\") = " << similarity << "\n\n"; + } + } + } // session destroyed before unload + + // 6. Unload when done (the destructor would also handle this). + model->Unload(); + } catch (const Error& ex) { + std::cerr << "Foundry Local error [" << ex.Code() << "]: " << ex.what() << "\n"; + return 1; + } + + return 0; +} diff --git a/samples/cpp/live-audio-transcription/README.md b/samples/cpp/live-audio-transcription/README.md deleted file mode 100644 index 3e8b8e8d6..000000000 --- a/samples/cpp/live-audio-transcription/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Live Audio Transcription Example (C++) - -Demonstrates real-time microphone-to-text using the Foundry Local C++ SDK. - -Uses [PortAudio](http://www.portaudio.com/) for cross-platform microphone capture -(the C/C++ equivalent of `naudiodon2` used by the JS sample). If PortAudio is not -available, falls back to synthetic PCM audio. - - -## Build - -```bash -# With PortAudio (live microphone) -g++ -std=c++20 -DHAS_PORTAUDIO main.cpp -lfoundry_local -lportaudio -o live-audio-transcription-example - -# Without PortAudio (synthetic audio only) -g++ -std=c++20 main.cpp -lfoundry_local -o live-audio-transcription-example -``` - -## Run - -```bash -# Live microphone (requires PortAudio) -./live-audio-transcription-example - -# Synthetic 440Hz sine wave (no microphone needed) -./live-audio-transcription-example --synth -``` - -Press `Ctrl+C` to request a graceful stop. The sample passes that signal to -execution-provider and model downloads so long-running downloads can be -cancelled before transcription starts. diff --git a/samples/cpp/live-audio-transcription/main.cpp b/samples/cpp/live-audio-transcription/main.cpp deleted file mode 100644 index 9068a46c3..000000000 --- a/samples/cpp/live-audio-transcription/main.cpp +++ /dev/null @@ -1,281 +0,0 @@ -// Live Audio Transcription — Foundry Local C++ SDK Example -// -// Demonstrates real-time microphone-to-text using the C++ SDK. -// Uses PortAudio for cross-platform mic capture (like naudiodon2 in the JS sample). -// Falls back to synthetic PCM if PortAudio is unavailable. -// -// Requires: PortAudio (libportaudio), Foundry Local C++ SDK -// -// Usage: ./live-audio-transcription-example [--synth] - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "foundry_local.h" - -// PortAudio is optional — compile with -DHAS_PORTAUDIO and link -lportaudio -// to enable live microphone capture. -#ifdef HAS_PORTAUDIO -#include -#endif - -namespace { - -// Global flag for Ctrl+C graceful shutdown (mirrors JS process.on('SIGINT')) -std::atomic g_running{true}; - -void SignalHandler(int /*signum*/) { - g_running = false; -} - -// Bounded audio queue (mirrors JS appendQueue with cap of 100) -class AudioQueue { -public: - void Push(std::vector chunk) { - std::lock_guard lock(mu_); - if (queue_.size() >= kMaxSize) { - queue_.pop_front(); - if (!warnedDrop_) { - warnedDrop_ = true; - std::cerr << "Audio append queue overflow; dropping oldest chunk to keep stream alive." << std::endl; - } - } - queue_.push_back(std::move(chunk)); - } - - bool TryPop(std::vector& out) { - std::lock_guard lock(mu_); - if (queue_.empty()) return false; - out = std::move(queue_.front()); - queue_.pop_front(); - return true; - } - -private: - static constexpr size_t kMaxSize = 100; - std::deque> queue_; - std::mutex mu_; - bool warnedDrop_ = false; -}; - -std::vector GenerateSineWavePcm(int sampleRate, int durationSeconds, double frequencyHz) { - const auto totalSamples = static_cast(sampleRate * durationSeconds); - std::vector pcm(totalSamples * 2, 0); // 16-bit mono, little-endian - - for (size_t i = 0; i < totalSamples; ++i) { - const double t = static_cast(i) / static_cast(sampleRate); - const auto sample = static_cast( - static_cast(INT16_MAX) * 0.5 * std::sin(2.0 * 3.14159265358979323846 * frequencyHz * t)); - const auto encodedSample = static_cast(sample); - pcm[i * 2] = static_cast(encodedSample & 0xFF); - pcm[i * 2 + 1] = static_cast((encodedSample >> 8) & 0xFF); - } - return pcm; -} - -#ifdef HAS_PORTAUDIO -// PortAudio callback — captures 16-bit mono PCM and pushes to the queue -int PaCallback(const void* input, void* /*output*/, - unsigned long frameCount, - const PaStreamCallbackTimeInfo* /*timeInfo*/, - PaStreamCallbackFlags /*statusFlags*/, - void* userData) { - auto* queue = static_cast(userData); - const auto* pcm = static_cast(input); - const size_t byteCount = frameCount * 2; // 16-bit mono = 2 bytes per frame - std::vector chunk(pcm, pcm + byteCount); - queue->Push(std::move(chunk)); - return g_running ? paContinue : paComplete; -} -#endif - -} // namespace - -int main(int argc, char* argv[]) { - bool useSynth = false; - for (int i = 1; i < argc; ++i) { - if (std::string(argv[i]) == "--synth") useSynth = true; - } - - // Install Ctrl+C handler (mirrors JS process.on('SIGINT')) - std::signal(SIGINT, SignalHandler); - - try { - std::cout << "===========================================================" << std::endl; - std::cout << " Foundry Local -- Live Audio Transcription Demo (C++)" << std::endl; - std::cout << "===========================================================" << std::endl; - std::cout << std::endl; - - foundry_local::Configuration config; - config.appName = "foundry_local_samples"; - - foundry_local::Manager::Create(config); - auto& manager = foundry_local::Manager::Instance(); - auto isCancellationRequested = [] { return !g_running.load(); }; - manager.DownloadAndRegisterEps(nullptr, isCancellationRequested); - - auto& catalog = manager.GetCatalog(); - // English-only: - const char* modelAlias = "nemotron-speech-streaming-en-0.6b"; - // Multi-lingual (supports 30+ languages including auto-detect): - // const char* modelAlias = "nemotron-3.5-asr-streaming-0.6b"; - auto* model = catalog.GetModel(modelAlias); - if (!model) { - throw std::runtime_error(std::string("Model \"") + modelAlias + "\" not found in catalog"); - } - - std::cout << "Downloading model (if needed)..." << std::endl; - model->Download( - [](float pct) { - std::cout << "\rDownloading: " << pct << "% " << std::flush; - return true; - }, - isCancellationRequested); - std::cout << std::endl; - std::cout << "Loading model..." << std::endl; - model->Load(); - std::cout << "Model loaded" << std::endl; - - // NOTE: CreateLiveTranscriptionSession() is not yet available in the C++ SDK. - // The audio client and session code below is forward-looking. - foundry_local::OpenAIAudioClient audioClient(*model); - auto session = audioClient.CreateLiveTranscriptionSession(); - - session->Settings().sample_rate = 16000; - session->Settings().channels = 1; - session->Settings().bits_per_sample = 16; - session->Settings().language = "en"; // English (default) - // Multi-lingual examples: - // session->Settings().language = "de"; // German - // session->Settings().language = "zh-CN"; // Chinese (Simplified) - // session->Settings().language = "auto"; // Auto-detect language - session->Start(); - std::cout << "Session started" << std::endl; - - // Read transcription results in a background thread (mirrors JS readPromise) - std::thread readThread([&session]() { - foundry_local::LiveAudioTranscriptionResponse result; - while (g_running) { - const auto status = session->TryGetNext(result, std::chrono::milliseconds(500)); - if (status == foundry_local::TranscriptionStatus::Result) { - if (result.is_final) { - std::cout << "\n [FINAL] " << result.text << std::endl; - } else if (!result.text.empty()) { - std::cout << result.text << std::flush; - } - } else if (status == foundry_local::TranscriptionStatus::Closed) { - break; - } else if (status == foundry_local::TranscriptionStatus::Timeout) { - continue; - } else { - std::cerr << "Transcription stream error: " << session->GetErrorMessage() << std::endl; - break; - } - } - }); - - // --- Microphone capture (mirrors JS naudiodon2 section) --- - // Uses PortAudio for cross-platform audio capture. If PortAudio is not - // available or --synth is passed, falls back to synthetic PCM. - - bool micActive = false; - -#ifdef HAS_PORTAUDIO - PaStream* paStream = nullptr; - AudioQueue audioQueue; - - if (!useSynth) { - PaError err = Pa_Initialize(); - if (err == paNoError) { - PaStreamParameters inputParams{}; - inputParams.device = Pa_GetDefaultInputDevice(); - if (inputParams.device != paNoDevice) { - inputParams.channelCount = 1; - inputParams.sampleFormat = paInt16; - inputParams.suggestedLatency = - Pa_GetDeviceInfo(inputParams.device)->defaultLowInputLatency; - inputParams.hostApiSpecificStreamInfo = nullptr; - - // framesPerBuffer=3200 matches JS framesPerBuffer setting - err = Pa_OpenStream(&paStream, &inputParams, nullptr, - 16000, 3200, paClipOff, - PaCallback, &audioQueue); - if (err == paNoError) { - err = Pa_StartStream(paStream); - } - } - - if (err == paNoError && paStream) { - micActive = true; - std::cout << std::endl; - std::cout << "===========================================================" << std::endl; - std::cout << " LIVE TRANSCRIPTION ACTIVE" << std::endl; - std::cout << " Speak into your microphone." << std::endl; - std::cout << " Press Ctrl+C to stop." << std::endl; - std::cout << "===========================================================" << std::endl; - std::cout << std::endl; - - // Pump audio from the queue to the session (mirrors JS pumpAudio) - while (g_running) { - std::vector chunk; - if (audioQueue.TryPop(chunk)) { - session->Append(chunk.data(), chunk.size()); - } else { - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - } - } - - Pa_StopStream(paStream); - Pa_CloseStream(paStream); - } else { - std::cerr << "Could not initialize microphone: " - << Pa_GetErrorText(err) << std::endl; - std::cerr << "Falling back to synthetic audio test..." << std::endl; - std::cerr << std::endl; - } - Pa_Terminate(); - } - } -#endif - - // Fallback: push synthetic PCM (440Hz sine wave) — mirrors JS catch block - if (!micActive) { - std::cout << "Pushing synthetic audio (440Hz sine, 2s)..." << std::endl; - const auto pcm = GenerateSineWavePcm(16000, 2, 440.0); - const size_t chunkSize = static_cast(16000 / 10 * 2); // 100ms - for (size_t offset = 0; offset < pcm.size() && g_running; offset += chunkSize) { - const size_t len = std::min(chunkSize, pcm.size() - offset); - session->Append(pcm.data() + offset, len); - std::this_thread::sleep_for(std::chrono::milliseconds(100)); - } - std::cout << "Synthetic audio pushed" << std::endl; - - // Wait briefly for remaining transcription results - std::this_thread::sleep_for(std::chrono::seconds(3)); - } - - // Graceful shutdown (mirrors JS SIGINT handler) - std::cout << "\n\nStopping..." << std::endl; - session->Stop(); - readThread.join(); - model->Unload(); - foundry_local::Manager::Destroy(); - std::cout << "Done" << std::endl; - return 0; - } catch (const std::exception& ex) { - std::cerr << "Error: " << ex.what() << std::endl; - foundry_local::Manager::Destroy(); - return 1; - } -} diff --git a/samples/cpp/responses-api/CMakeLists.txt b/samples/cpp/responses-api/CMakeLists.txt new file mode 100644 index 000000000..55ba58c71 --- /dev/null +++ b/samples/cpp/responses-api/CMakeLists.txt @@ -0,0 +1,28 @@ +# Copyright (c) Microsoft. All rights reserved. +# +# Standalone build for the Foundry Local C++ "responses-api" (vision) sample. +# Build the SDK first: python ../../../sdk_v2/cpp/build.py +# Then: cmake -S . -B build && cmake --build build + +cmake_minimum_required(VERSION 3.20) +project(foundry_local_responses_api_sample CXX) + +set(CMAKE_CXX_STANDARD 20) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +# Locate the locally-built SDK and define the foundry_local_cpp target. +include(${CMAKE_CURRENT_LIST_DIR}/../cmake/FoundryLocalSDK.cmake) + +add_executable(responses_api main.cc) + +# Shared sample helpers (HTTP client, base64) live in samples/cpp/common. +target_include_directories(responses_api PRIVATE ${CMAKE_CURRENT_LIST_DIR}/..) +target_link_libraries(responses_api PRIVATE foundry_local_cpp) + +# Absolute path to this sample dir so the bundled test image is found regardless +# of where the executable runs from. +target_compile_definitions(responses_api PRIVATE SAMPLE_SOURCE_DIR="${CMAKE_CURRENT_LIST_DIR}") + +# Bake in the rpath so the executable finds the SDK shared library at runtime. +foundry_local_configure_sample(responses_api) diff --git a/samples/cpp/responses-api/README.md b/samples/cpp/responses-api/README.md new file mode 100644 index 000000000..95ac34739 --- /dev/null +++ b/samples/cpp/responses-api/README.md @@ -0,0 +1,65 @@ +# Responses API — Vision (C++) + +Demonstrates **image understanding** with the Foundry Local C++ SDK (`sdk_v2/cpp`) +through the OpenAI-compatible **Responses API** (`POST /v1/responses`). + +The Responses API is exposed by the embedded **web service**, so this sample hosts +that service in-process with `AddWebServiceEndpoint` + `StartWebService`, then sends +an image + prompt over loopback HTTP and prints the model's description. + +This sample tracks **`main`** — it builds against your **local** `sdk_v2/cpp` build, +not a pinned SDK release. + +## What it does + +1. Creates a `Manager` with an embedded web service endpoint + (`http://127.0.0.1:0` — an ephemeral port). +2. Resolves a vision-capable model (default: `qwen3.5-0.8b`), downloading + + loading it if needed. +3. Starts the web service and discovers the bound URL via `GetWebServiceEndpoints()`. +4. Base64-encodes a bundled image into a `data:image/jpeg;base64,...` URL. +5. POSTs a Responses API request whose message has an `input_text` part and an + `input_image` part, then prints the response's `output_text`. + +A small default image (`test_image.jpg`, 256×256) ships with the sample so it runs +out of the box. + +> **Image input format.** The sdk_v2 Responses API expects `input_image.image_url` +> to be either a `data:` URL (used here) or a local file path — remote `http(s)` +> image URLs are not supported. This differs from the v1 sample, which used a +> separate `image_data` + `media_type` shape. +> +> **Model id vs alias.** The web service resolves models by their full **variant +> id** (from `ModelInfo::Id()`), not the short alias. + +## Prerequisites + +```bash +python ../../../sdk_v2/cpp/build.py +``` + +## Build + +```bash +cmake -S . -B build +cmake --build build +``` + +Override the SDK config/location if needed: +`-DFOUNDRY_LOCAL_BUILD_CONFIG=Debug`, `-DFOUNDRY_LOCAL_SDK_DIR=...`, +`-DFOUNDRY_LOCAL_BUILD_DIR=...`. + +## Run + +```bash +# Default vision model + bundled image: +./build/responses_api # Windows: .\build\responses_api.exe + +# Custom vision model: +./build/responses_api qwen3.5-0.8b + +# Custom model + custom image: +./build/responses_api qwen3.5-0.8b /path/to/image.jpg +``` + +The first run downloads the model; later runs use the cache. diff --git a/samples/cpp/responses-api/main.cc b/samples/cpp/responses-api/main.cc new file mode 100644 index 000000000..6ec24b7a2 --- /dev/null +++ b/samples/cpp/responses-api/main.cc @@ -0,0 +1,148 @@ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. +// +// Sample: Vision / image understanding via the Foundry Local embedded web service +// and the OpenAI Responses API (POST /v1/responses). +// +// Flow: +// 1. Host the web service (AddWebServiceEndpoint + StartWebService). +// 2. Load a vision-capable model. +// 3. Base64-encode a local image into a `data:` URL. +// 4. POST /v1/responses with an `input_text` + `input_image` message. +// 5. Print the model's description from the response's `output_text`. +// +// The Responses API is only exposed over the web service, so — unlike the chat +// and embeddings samples — vision here goes through HTTP rather than a native +// in-process session. + +#include + +#include + +#include +#include +#include +#include +#include + +#include "common/base64.h" +#include "common/local_http_client.h" + +using namespace foundry_local; +using json = nlohmann::json; + +namespace { + +// Default vision model alias (overridable on the command line), matching the +// other-language responses-vision samples. +constexpr const char* kDefaultModelAlias = "qwen3.5-0.8b"; + +/// Read an entire file into a byte buffer. Throws std::runtime_error if it can't be opened. +std::vector ReadFileBytes(const std::filesystem::path& path) { + std::ifstream file(path, std::ios::binary); + if (!file) { + throw std::runtime_error("Failed to open image: " + path.string()); + } + + return std::vector((std::istreambuf_iterator(file)), std::istreambuf_iterator()); +} + +/// Build the /v1/responses request body: one user message with text + image content. +json BuildVisionRequest(const std::string& model_id, const std::string& data_url, const std::string& prompt) { + return json{ + {"model", model_id}, + {"stream", false}, + {"input", + json::array({{{"type", "message"}, + {"role", "user"}, + {"content", json::array({{{"type", "input_text"}, {"text", prompt}}, + {{"type", "input_image"}, {"image_url", data_url}}})}}})}}; +} + +} // namespace + +int main(int argc, char* argv[]) { + const std::string model_alias = argc > 1 ? argv[1] : kDefaultModelAlias; + + // Default to the bundled test image; allow an override as the second argument. + std::filesystem::path image_path = + argc > 2 ? std::filesystem::path(argv[2]) : std::filesystem::path(SAMPLE_SOURCE_DIR) / "test_image.jpg"; + + try { + // 1. Configure the SDK with an embedded web service endpoint. + Configuration config("foundry_local_samples"); + config.AddWebServiceEndpoint("http://127.0.0.1:0"); + + Manager manager(std::move(config)); + + // 2. Resolve and prepare the vision model. + auto& catalog = manager.GetCatalog(); + auto model = catalog.GetModel(model_alias); + if (!model) { + std::cerr << "Model '" << model_alias << "' not found in catalog.\n"; + return 1; + } + + std::cout << "Using model: " << model->GetInfo().Name() << "\n"; + + if (!model->IsCached()) { + std::cout << "Downloading...\n"; + model->Download([](float progress) -> int { + std::cout << "\r " << static_cast(progress) << "%" << std::flush; + return 0; // return non-zero to cancel + }); + std::cout << "\n"; + } + + if (!model->IsLoaded()) { + std::cout << "Loading model...\n"; + model->Load(); + } + + // 3. Start the web service and discover its bound URL. + std::cout << "\n=== Starting web service ===\n"; + manager.StartWebService(); + + const std::vector endpoints = manager.GetWebServiceEndpoints(); + if (endpoints.empty()) { + std::cerr << "Web service did not report any endpoints.\n"; + return 1; + } + + const sample::http::Url url = sample::http::ParseUrl(endpoints[0]); + std::cout << "Web service listening at " << endpoints[0] << "\n"; + + // 4. Encode the image as a base64 data URL (the Responses API requires a + // `data:;base64,` URL or a local file path for input_image). + std::cout << "\n=== Vision request (POST /v1/responses) ===\n"; + std::cout << "Image: " << image_path.string() << "\n"; + + const std::vector image_bytes = ReadFileBytes(image_path); + const std::string data_url = "data:image/jpeg;base64," + sample::Base64Encode(image_bytes); + + const json body = BuildVisionRequest(std::string(model->GetInfo().Id()), data_url, "Describe this image in detail."); + + const sample::http::Response response = sample::http::Post(url.host, url.port, "/v1/responses", body.dump()); + + if (response.status != 200) { + std::cerr << "HTTP " << response.status << ": " << response.body << "\n"; + manager.StopWebService(); + return 1; + } + + // 5. Print the assistant's description. + const json parsed = json::parse(response.body); + std::cout << "\nAssistant: " << parsed.value("output_text", "") << "\n"; + + manager.StopWebService(); + model->Unload(); + } catch (const Error& ex) { + std::cerr << "Foundry Local error [" << ex.Code() << "]: " << ex.what() << "\n"; + return 1; + } catch (const std::exception& ex) { + std::cerr << "Error: " << ex.what() << "\n"; + return 1; + } + + return 0; +} diff --git a/samples/cs/foundry-local-web-server-responses-vision/test_image.jpg b/samples/cpp/responses-api/test_image.jpg similarity index 100% rename from samples/cs/foundry-local-web-server-responses-vision/test_image.jpg rename to samples/cpp/responses-api/test_image.jpg diff --git a/samples/cs/Directory.Packages.props b/samples/cs/Directory.Packages.props index 77b68c4cc..f8d39f79d 100644 --- a/samples/cs/Directory.Packages.props +++ b/samples/cs/Directory.Packages.props @@ -1,12 +1,14 @@ true - true - - - + diff --git a/samples/cs/README.md b/samples/cs/README.md index fb594717e..1de9aa441 100644 --- a/samples/cs/README.md +++ b/samples/cs/README.md @@ -1,29 +1,20 @@ # 🚀 Foundry Local C# Samples -These samples demonstrate how to use the Foundry Local C# SDK. Each sample uses a **unified project file** that automatically detects your operating system and selects the optimal NuGet package: +These samples demonstrate how to use the Foundry Local C# SDK. -- **Windows**: Uses `Microsoft.AI.Foundry.Local.WinML` for hardware acceleration via Windows ML. -- **macOS / Linux**: Uses `Microsoft.AI.Foundry.Local` for cross-platform support. - -Both packages provide the same APIs, so the same source code works on all platforms. +They **track `main`** and consume the SDK **from local source** via a `ProjectReference` to +`sdk/cs/src/Microsoft.AI.Foundry.Local.csproj` — they are **not** pinned to a published package +version. The `Microsoft.AI.Foundry.Local.Core*` packages and native runtime assets flow +transitively from that SDK project and restore from nuget.org, along with any third-party packages. ## Samples | Sample | Description | |---|---| -| [native-chat-completions](native-chat-completions/) | Initialize the SDK, download a model, and run chat completions. | +| [chat-completion](chat-completion/) | Run the same chat prompt two ways: native in-process inference **and** the local OpenAI-compatible web server (`/v1/chat/completions`). | | [embeddings](embeddings/) | Generate single and batch text embeddings using the Foundry Local SDK. | -| [audio-transcription-example](audio-transcription-example/) | Transcribe audio files using the Foundry Local SDK. | -| [foundry-local-web-server](foundry-local-web-server/) | Set up a local OpenAI-compliant web server. | -| [foundry-local-web-server-responses-vision](foundry-local-web-server-responses-vision/) | Stream a vision (image understanding) response from the local web server using the Responses API. | -| [tool-calling-foundry-local-sdk](tool-calling-foundry-local-sdk/) | Use tool calling with native chat completions. | -| [tool-calling-foundry-local-web-server](tool-calling-foundry-local-web-server/) | Use tool calling with the local web server. | -| [model-management-example](model-management-example/) | Manage models, variant selection, and updates. | -| [tutorial-chat-assistant](tutorial-chat-assistant/) | Build an interactive chat assistant (tutorial). | -| [tutorial-document-summarizer](tutorial-document-summarizer/) | Summarize documents with AI (tutorial). | -| [tutorial-tool-calling](tutorial-tool-calling/) | Create a tool-calling assistant (tutorial). | -| [tutorial-voice-to-text](tutorial-voice-to-text/) | Transcribe and summarize audio (tutorial). | - +| [audio](audio/) | Live microphone streaming transcription (Nemotron ASR) **and** file-based transcription (Whisper) via `--file [path]`. | +| [responses-api](responses-api/) | Stream a vision (image understanding) response from the local web server using the Responses API. | ## Running a sample @@ -33,9 +24,10 @@ Both packages provide the same APIs, so the same source code works on all platfo cd Foundry-Local/samples/cs ``` -2. Open and run a sample: +2. Build and run a sample (the SDK is resolved from `sdk/cs` source via the project reference; + `Microsoft.AI.Foundry.Local.Core` and third-party packages restore from nuget.org): ```bash - cd native-chat-completions + cd chat-completion + dotnet build dotnet run ``` - diff --git a/samples/cs/audio-transcription-example/AudioTranscriptionExample.sln b/samples/cs/audio-transcription-example/AudioTranscriptionExample.sln deleted file mode 100644 index 46fb73d98..000000000 --- a/samples/cs/audio-transcription-example/AudioTranscriptionExample.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AudioTranscriptionExample", "AudioTranscriptionExample.csproj", "{11616852-BB4F-4B60-9FAC-D94E2688BB30}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Debug|Any CPU.ActiveCfg = Debug|ARM64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Debug|Any CPU.Build.0 = Debug|ARM64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Debug|x64.ActiveCfg = Debug|x64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Debug|x64.Build.0 = Debug|x64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Debug|x86.ActiveCfg = Debug|ARM64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Debug|x86.Build.0 = Debug|ARM64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Release|Any CPU.ActiveCfg = Release|ARM64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Release|Any CPU.Build.0 = Release|ARM64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Release|x64.ActiveCfg = Release|x64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Release|x64.Build.0 = Release|x64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Release|x86.ActiveCfg = Release|ARM64 - {11616852-BB4F-4B60-9FAC-D94E2688BB30}.Release|x86.Build.0 = Release|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/samples/cs/audio-transcription-example/Program.cs b/samples/cs/audio-transcription-example/Program.cs deleted file mode 100644 index 10047421a..000000000 --- a/samples/cs/audio-transcription-example/Program.cs +++ /dev/null @@ -1,87 +0,0 @@ -// -// -using Microsoft.AI.Foundry.Local; -// - -// -var config = new Configuration -{ - AppName = "foundry_local_samples", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information -}; - - -// Initialize the singleton instance. -await FoundryLocalManager.CreateAsync(config, Utils.GetAppLogger()); -var mgr = FoundryLocalManager.Instance; - - -// Ensure that any Execution Provider (EP) downloads run and are completed. -// Download and register all execution providers. -var currentEp = ""; -await mgr.DownloadAndRegisterEpsAsync((epName, percent) => -{ - if (epName != currentEp) - { - if (currentEp != "") Console.WriteLine(); - currentEp = epName; - } - Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%"); -}); -if (currentEp != "") Console.WriteLine(); -// - - -// -// Get the model catalog -var catalog = await mgr.GetCatalogAsync(); - - -// Get a model using an alias and select the CPU model variant -var model = await catalog.GetModelAsync("whisper-tiny") ?? throw new System.Exception("Model not found"); -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 => -{ - Console.Write($"\rDownloading model: {progress:F2}%"); - if (progress >= 100f) - { - Console.WriteLine(); - } -}); - - -// Load the model -Console.Write($"Loading model {model.Id}..."); -await model.LoadAsync(); -Console.WriteLine("done."); -// - - -// -// Get an audio client -var audioClient = await model.GetAudioClientAsync(); -audioClient.Settings.Language = "en"; - -// Get a transcription with streaming outputs -var audioFile = args.Length > 0 ? args[0] : Path.Combine(AppContext.BaseDirectory, "Recording.mp3"); -Console.WriteLine($"Transcribing audio with streaming output: {Path.GetFileName(audioFile)}"); -var response = audioClient.TranscribeAudioStreamingAsync(audioFile, 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(); -// -// \ No newline at end of file diff --git a/samples/cs/live-audio-transcription/LiveAudioTranscriptionExample.csproj b/samples/cs/audio/Audio.csproj similarity index 63% rename from samples/cs/live-audio-transcription/LiveAudioTranscriptionExample.csproj rename to samples/cs/audio/Audio.csproj index 4a0eed349..c15692090 100644 --- a/samples/cs/live-audio-transcription/LiveAudioTranscriptionExample.csproj +++ b/samples/cs/audio/Audio.csproj @@ -11,14 +11,11 @@ $(NETCoreSdkRuntimeIdentifier) - - - - - - - - + + + @@ -27,6 +24,13 @@ + + + + PreserveNewest + + + diff --git a/samples/cs/live-audio-transcription/LiveAudioTranscriptionExample.sln b/samples/cs/audio/Audio.sln similarity index 90% rename from samples/cs/live-audio-transcription/LiveAudioTranscriptionExample.sln rename to samples/cs/audio/Audio.sln index f8c882849..4d80abe67 100644 --- a/samples/cs/live-audio-transcription/LiveAudioTranscriptionExample.sln +++ b/samples/cs/audio/Audio.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LiveAudioTranscriptionExample", "LiveAudioTranscriptionExample.csproj", "{A2B3C4D5-E6F7-4A8B-9C0D-1E2F3A4B5C6D}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Audio", "Audio.csproj", "{A2B3C4D5-E6F7-4A8B-9C0D-1E2F3A4B5C6D}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/samples/cs/live-audio-transcription/Program.cs b/samples/cs/audio/Program.cs similarity index 68% rename from samples/cs/live-audio-transcription/Program.cs rename to samples/cs/audio/Program.cs index 9caa2569d..810ff8f16 100644 --- a/samples/cs/live-audio-transcription/Program.cs +++ b/samples/cs/audio/Program.cs @@ -1,13 +1,30 @@ -// Live Audio Transcription — Foundry Local SDK Example +// Audio Transcription — Foundry Local SDK Example // -// NAudio's WaveInEvent is Windows-only. On non-Windows platforms, the sample -// falls back to synthetic PCM audio. +// Two modes: +// * Default (no --file): live microphone streaming transcription with Nemotron ASR. +// NAudio's WaveInEvent is Windows-only. On non-Windows platforms (or with --synth) +// the sample falls back to synthetic PCM audio. +// * --file [path]: file-based transcription with Whisper. Uses the bundled Recording.mp3 +// when no path is supplied. using Microsoft.AI.Foundry.Local; using NAudio.Wave; +// Parse CLI options. +int fileFlagIndex = Array.IndexOf(args, "--file"); +bool fileMode = fileFlagIndex >= 0; +bool useSynth = args.Contains("--synth"); + +string defaultAudioFile = Path.Combine(AppContext.BaseDirectory, "Recording.mp3"); +string audioFile = defaultAudioFile; +if (fileMode && fileFlagIndex + 1 < args.Length && !args[fileFlagIndex + 1].StartsWith("--", StringComparison.Ordinal)) +{ + audioFile = args[fileFlagIndex + 1]; +} + Console.WriteLine("==========================================================="); -Console.WriteLine(" Foundry Local -- Live Audio Transcription Demo"); +Console.WriteLine(" Foundry Local -- Audio Transcription Demo"); +Console.WriteLine($" Mode: {(fileMode ? "file (Whisper)" : "live microphone (Nemotron ASR)")}"); Console.WriteLine("==========================================================="); Console.WriteLine(); @@ -24,6 +41,52 @@ var catalog = await mgr.GetCatalogAsync(); +if (fileMode) +{ + // ===== File-based transcription (Whisper) ===== + if (!File.Exists(audioFile)) + { + Console.Error.WriteLine($"Audio file not found: {audioFile}"); + return 1; + } + + // Get the Whisper model and select the CPU variant. + var fileModel = await catalog.GetModelAsync("whisper-tiny") ?? throw new Exception("Model \"whisper-tiny\" not found in catalog"); + var modelVariant = fileModel.Variants.First(v => v.Info.Runtime?.DeviceType == DeviceType.CPU); + fileModel.SelectVariant(modelVariant); + + await fileModel.DownloadAsync(progress => + { + Console.Write($"\rDownloading model: {progress:F2}%"); + if (progress >= 100f) + { + Console.WriteLine(); + } + }); + + Console.Write($"Loading model {fileModel.Id}..."); + await fileModel.LoadAsync(); + Console.WriteLine("done."); + + var fileAudioClient = await fileModel.GetAudioClientAsync(); + fileAudioClient.Settings.Language = "en"; + + Console.WriteLine($"Transcribing audio file: {Path.GetFileName(audioFile)}"); + Console.Write("[TRANSCRIPT]: "); + var fileResponse = fileAudioClient.TranscribeAudioStreamingAsync(audioFile, CancellationToken.None); + await foreach (var chunk in fileResponse) + { + Console.Write(chunk.Text); + Console.Out.Flush(); + } + Console.WriteLine(); + + await fileModel.UnloadAsync(); + return 0; +} + +// ===== Live microphone transcription (Nemotron ASR) ===== + // English-only: var modelAlias = "nemotron-speech-streaming-en-0.6b"; // Multi-lingual (supports 30+ languages including auto-detect): @@ -82,8 +145,6 @@ await model.DownloadAsync(progress => catch (OperationCanceledException) { } }); -bool useSynth = args.Contains("--synth"); - // NAudio WaveInEvent is Windows-only. On other platforms, fall back to synthetic audio. if (!useSynth && OperatingSystem.IsWindows()) { @@ -141,6 +202,7 @@ await model.DownloadAsync(progress => if (!OperatingSystem.IsWindows() && !useSynth) { Console.WriteLine("NAudio mic capture is Windows-only. Falling back to synthetic audio..."); + Console.WriteLine("(Use --file [path] for file-based Whisper transcription instead.)"); } // Synthetic PCM fallback: 440Hz sine wave, 2 seconds @@ -173,3 +235,4 @@ await model.DownloadAsync(progress => await readTask; await model.UnloadAsync(); +return 0; diff --git a/samples/cs/audio/README.md b/samples/cs/audio/README.md new file mode 100644 index 000000000..e52f63ce4 --- /dev/null +++ b/samples/cs/audio/README.md @@ -0,0 +1,104 @@ +# Audio Transcription Example + +One sample, two transcription modes against Foundry Local: + +- **Live microphone streaming** (default) with **Nemotron ASR** — real-time speech-to-text. +- **File-based transcription** with **Whisper** via the `--file [path]` option. + +## Prerequisites + +- [Foundry Local](https://github.com/microsoft/Foundry-Local) installed +- .NET 9 SDK +- A microphone for live mode (optional — falls back to synthetic audio on non-Windows or with `--synth`) + +> **Note:** Microphone capture uses [NAudio](https://github.com/naudio/NAudio) and is Windows-only. +> On other platforms the live mode falls back to synthetic audio; use `--file` for real +> transcription of an audio file. + +## SDK consumption + +This sample tracks `main`: it consumes the Foundry Local C# SDK **from local source** via a +`ProjectReference` to `sdk/cs/src/Microsoft.AI.Foundry.Local.csproj`. It is **not** version-pinned +to a published package. The `Microsoft.AI.Foundry.Local.Core*` packages and native runtime assets +flow transitively from that project and restore from nuget.org, along with the third-party `NAudio` +and `Microsoft.Extensions.Logging` packages. + +## Build & run + +```bash +# from this directory +dotnet build +``` + +`dotnet build` resolves the SDK from `sdk/cs` source via the project reference and restores +`Microsoft.AI.Foundry.Local.Core` plus third-party packages from nuget.org. + +### Live microphone transcription (default — Nemotron ASR) + +```bash +dotnet run +``` + +Speak into your microphone. Transcription appears in real-time (cyan text). Press `ENTER` to stop. + +To force synthetic audio (e.g., for CI or non-Windows): + +```bash +dotnet run -- --synth +``` + +### File-based transcription (Whisper) + +```bash +# transcribe the bundled Recording.mp3 +dotnet run -- --file + +# transcribe your own file +dotnet run -- --file /path/to/audio.wav +``` + +A small `Recording.mp3` is bundled and used as the default when no path is given. + +## How it works + +### Live mode (Nemotron ASR) + +1. Loads the Nemotron streaming ASR model. +2. Creates a live transcription session (`audioClient.CreateLiveTranscriptionSession()`) with + 16kHz / 16-bit / mono PCM settings. +3. Captures microphone audio via `NAudio.WaveInEvent` (or generates synthetic audio as a fallback). +4. Pushes PCM chunks via `session.AppendAsync()` through a bounded channel for backpressure. +5. Reads results via `await foreach (var result in session.GetStream())`. + +### File mode (Whisper) + +1. Loads the `whisper-tiny` model and selects its CPU variant. +2. Streams the transcript via `audioClient.TranscribeAudioStreamingAsync(path)`. + +## API + +```csharp +// Live streaming +var audioClient = await model.GetAudioClientAsync(); +var session = audioClient.CreateLiveTranscriptionSession(); +session.Settings.SampleRate = 16000; +session.Settings.Channels = 1; +session.Settings.Language = "en"; + +await session.StartAsync(); +await session.AppendAsync(pcmBytes); // push audio +await foreach (var result in session.GetStream()) +{ + Console.WriteLine(result.Content[0].Text); // transcribed text + Console.WriteLine(result.IsFinal); // true for final results +} +await session.StopAsync(); + +// File transcription +var audioClient = await model.GetAudioClientAsync(); +audioClient.Settings.Language = "en"; +await foreach (var chunk in audioClient.TranscribeAudioStreamingAsync(path)) +{ + Console.Write(chunk.Text); +} +``` diff --git a/samples/cs/audio-transcription-example/Recording.mp3 b/samples/cs/audio/Recording.mp3 similarity index 100% rename from samples/cs/audio-transcription-example/Recording.mp3 rename to samples/cs/audio/Recording.mp3 diff --git a/samples/cs/tool-calling-foundry-local-web-server/ToolCallingFoundryLocalWebServer.csproj b/samples/cs/chat-completion/ChatCompletion.csproj similarity index 66% rename from samples/cs/tool-calling-foundry-local-web-server/ToolCallingFoundryLocalWebServer.csproj rename to samples/cs/chat-completion/ChatCompletion.csproj index 77fc929d6..612b951d8 100644 --- a/samples/cs/tool-calling-foundry-local-web-server/ToolCallingFoundryLocalWebServer.csproj +++ b/samples/cs/chat-completion/ChatCompletion.csproj @@ -11,14 +11,11 @@ $(NETCoreSdkRuntimeIdentifier) - - - - - - - - + + + @@ -27,6 +24,7 @@ + diff --git a/samples/cs/native-chat-completions/NativeChatCompletions.sln b/samples/cs/chat-completion/ChatCompletion.sln similarity index 91% rename from samples/cs/native-chat-completions/NativeChatCompletions.sln rename to samples/cs/chat-completion/ChatCompletion.sln index a127bfba6..3bb56f391 100644 --- a/samples/cs/native-chat-completions/NativeChatCompletions.sln +++ b/samples/cs/chat-completion/ChatCompletion.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NativeChatCompletions", "NativeChatCompletions.csproj", "{A53372CE-F7E1-4F09-B186-77F76E388659}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ChatCompletion", "ChatCompletion.csproj", "{A53372CE-F7E1-4F09-B186-77F76E388659}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/samples/cs/native-chat-completions/Program.cs b/samples/cs/chat-completion/Program.cs similarity index 57% rename from samples/cs/native-chat-completions/Program.cs rename to samples/cs/chat-completion/Program.cs index 033786b1f..9f011b0c0 100644 --- a/samples/cs/native-chat-completions/Program.cs +++ b/samples/cs/chat-completion/Program.cs @@ -1,16 +1,30 @@ // +// This sample demonstrates two ways to run the same chat prompt against Foundry Local: +// 1. Native, in-process inference via the SDK's chat client. +// 2. The local OpenAI-compatible web server (/v1/chat/completions) via the OpenAI SDK. +// // using Microsoft.AI.Foundry.Local; using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels; +using OpenAI; +using System.ClientModel; // +// The same prompt is used for both the native and web-server demonstrations. +const string prompt = "Why is the sky blue?"; + // CancellationToken ct = new CancellationToken(); var config = new Configuration { AppName = "foundry_local_samples", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information + LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information, + // The web server is started later for the second demonstration. + Web = new Configuration.WebService + { + Urls = "http://127.0.0.1:52495" + } }; @@ -83,18 +97,20 @@ await model.DownloadAsync(progress => Console.WriteLine("done."); // -// -// Get a chat client +// +// === Native inference === +// Run the prompt with the SDK's in-process chat client (no web server involved). +Console.WriteLine(); +Console.WriteLine("=== Native inference ==="); + var chatClient = await model.GetChatClientAsync(); -// Create a chat message List messages = new() { - new ChatMessage { Role = "user", Content = "Why is the sky blue?" } + new ChatMessage { Role = "user", Content = prompt } }; -// Get a streaming chat completion response -Console.WriteLine("Chat completion response:"); +Console.Write("[ASSISTANT]: "); var streamingResponse = chatClient.CompleteChatStreamingAsync(messages, ct); await foreach (var chunk in streamingResponse) { @@ -102,10 +118,44 @@ await model.DownloadAsync(progress => Console.Out.Flush(); } Console.WriteLine(); -// +// + +// +// === Web server (/v1/chat/completions) === +// Run the same prompt against the local OpenAI-compatible web server using the OpenAI SDK. +Console.WriteLine(); +Console.WriteLine("=== Web server (/v1/chat/completions) ==="); + +Console.Write($"Starting web service on {config.Web.Urls}..."); +await mgr.StartWebServiceAsync(); +Console.WriteLine("done."); + +// Use the OpenAI SDK to call the local Foundry web service. +ApiKeyCredential key = new ApiKeyCredential("notneeded"); +OpenAIClient client = new OpenAIClient(key, new OpenAIClientOptions +{ + Endpoint = new Uri(config.Web.Urls + "/v1"), +}); + +var webChatClient = client.GetChatClient(model.Id); +var completionUpdates = webChatClient.CompleteChatStreaming(prompt); + +Console.Write("[ASSISTANT]: "); +foreach (var completionUpdate in completionUpdates) +{ + if (completionUpdate.ContentUpdate.Count > 0) + { + Console.Write(completionUpdate.ContentUpdate[0].Text); + } +} +Console.WriteLine(); + +// Stop the web service. +await mgr.StopWebServiceAsync(); +// // // Tidy up - unload the model await model.UnloadAsync(); // -// \ No newline at end of file +// diff --git a/samples/cs/chat-completion/README.md b/samples/cs/chat-completion/README.md new file mode 100644 index 000000000..5747a4db8 --- /dev/null +++ b/samples/cs/chat-completion/README.md @@ -0,0 +1,48 @@ +# Native Chat Completions Example + +Run the same chat prompt against Foundry Local two ways from a single program: + +1. **Native, in-process inference** via the SDK's chat client (no web server involved). +2. **The local OpenAI-compatible web server** (`/v1/chat/completions`) via the [OpenAI .NET SDK](https://www.nuget.org/packages/OpenAI). + +The program prints clear section headers so you can compare the two paths: + +``` +=== Native inference === +[ASSISTANT]: ... + +=== Web server (/v1/chat/completions) === +[ASSISTANT]: ... +``` + +## Prerequisites + +- [Foundry Local](https://github.com/microsoft/Foundry-Local) installed +- .NET 9 SDK + +## SDK consumption + +This sample tracks `main`: it consumes the Foundry Local C# SDK **from local source** via a +`ProjectReference` to `sdk/cs/src/Microsoft.AI.Foundry.Local.csproj`. It is **not** version-pinned +to a published package. The `Microsoft.AI.Foundry.Local.Core*` packages and native runtime assets +flow transitively from that project and restore from nuget.org, along with the third-party +`OpenAI` package. + +## Build & run + +```bash +# from this directory +dotnet build +dotnet run +``` + +`dotnet build` resolves the SDK from `sdk/cs` source via the project reference and restores +`Microsoft.AI.Foundry.Local.Core` plus third-party packages from nuget.org. + +## What it does + +1. Initializes the SDK and downloads/registers execution providers. +2. Downloads and loads the `qwen2.5-0.5b` model. +3. Streams the prompt through the native chat client. +4. Starts the local web server and streams the same prompt through the OpenAI SDK. +5. Stops the web server and unloads the model. diff --git a/samples/cs/embeddings/Embeddings.csproj b/samples/cs/embeddings/Embeddings.csproj index 97cb8ef34..964248cba 100644 --- a/samples/cs/embeddings/Embeddings.csproj +++ b/samples/cs/embeddings/Embeddings.csproj @@ -11,14 +11,11 @@ $(NETCoreSdkRuntimeIdentifier) - - - - - - - - + + + diff --git a/samples/cs/embeddings/README.md b/samples/cs/embeddings/README.md new file mode 100644 index 000000000..5522f375b --- /dev/null +++ b/samples/cs/embeddings/README.md @@ -0,0 +1,33 @@ +# Embeddings Example + +Generate single and batch text embeddings natively (in-process) with the Foundry Local C# SDK. + +## Prerequisites + +- [Foundry Local](https://github.com/microsoft/Foundry-Local) installed +- .NET 9 SDK + +## SDK consumption + +This sample tracks `main`: it consumes the Foundry Local C# SDK **from local source** via a +`ProjectReference` to `sdk/cs/src/Microsoft.AI.Foundry.Local.csproj`. It is **not** version-pinned +to a published package. The `Microsoft.AI.Foundry.Local.Core*` packages and native runtime assets +flow transitively from that project and restore from nuget.org. + +## Build & run + +```bash +# from this directory +dotnet build +dotnet run +``` + +`dotnet build` resolves the SDK from `sdk/cs` source via the project reference and restores +`Microsoft.AI.Foundry.Local.Core` from nuget.org. + +## What it does + +1. Initializes the SDK and downloads/loads the `qwen3-embedding-0.6b` model. +2. Generates a single embedding and prints its dimensions and first values. +3. Generates a batch of embeddings and prints the dimensions for each. +4. Unloads the model. diff --git a/samples/cs/foundry-local-web-server-responses-vision/FoundryLocalWebServerResponsesVision.csproj b/samples/cs/foundry-local-web-server-responses-vision/FoundryLocalWebServerResponsesVision.csproj deleted file mode 100644 index 06e29a5d2..000000000 --- a/samples/cs/foundry-local-web-server-responses-vision/FoundryLocalWebServerResponsesVision.csproj +++ /dev/null @@ -1,54 +0,0 @@ - - - - Exe - enable - enable - - - - - net9.0-windows10.0.18362.0 - ARM64;x64 - None - false - - - - - net9.0 - - - - $(NETCoreSdkRuntimeIdentifier) - - - - - - - - - - - - - - - - - - - - - - PreserveNewest - - - - - - - - - diff --git a/samples/cs/foundry-local-web-server/FoundryLocalWebServer.csproj b/samples/cs/foundry-local-web-server/FoundryLocalWebServer.csproj deleted file mode 100644 index 77fc929d6..000000000 --- a/samples/cs/foundry-local-web-server/FoundryLocalWebServer.csproj +++ /dev/null @@ -1,39 +0,0 @@ - - - - Exe - enable - enable - net9.0 - - - - $(NETCoreSdkRuntimeIdentifier) - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/cs/foundry-local-web-server/FoundryLocalWebServer.sln b/samples/cs/foundry-local-web-server/FoundryLocalWebServer.sln deleted file mode 100644 index 91d7e9536..000000000 --- a/samples/cs/foundry-local-web-server/FoundryLocalWebServer.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoundryLocalWebServer", "FoundryLocalWebServer.csproj", "{2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Debug|Any CPU.ActiveCfg = Debug|ARM64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Debug|Any CPU.Build.0 = Debug|ARM64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Debug|x64.ActiveCfg = Debug|x64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Debug|x64.Build.0 = Debug|x64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Debug|x86.ActiveCfg = Debug|ARM64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Debug|x86.Build.0 = Debug|ARM64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Release|Any CPU.ActiveCfg = Release|ARM64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Release|Any CPU.Build.0 = Release|ARM64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Release|x64.ActiveCfg = Release|x64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Release|x64.Build.0 = Release|x64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Release|x86.ActiveCfg = Release|ARM64 - {2DEC84E5-8530-45AF-B26D-EC78A6A7D6E7}.Release|x86.Build.0 = Release|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/samples/cs/foundry-local-web-server/Program.cs b/samples/cs/foundry-local-web-server/Program.cs deleted file mode 100644 index eb88e4b39..000000000 --- a/samples/cs/foundry-local-web-server/Program.cs +++ /dev/null @@ -1,100 +0,0 @@ -// -// -using Microsoft.AI.Foundry.Local; -using OpenAI; -using System.ClientModel; -// - -// -var config = new Configuration -{ - AppName = "foundry_local_samples", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information, - Web = new Configuration.WebService - { - Urls = "http://127.0.0.1:52495" - } -}; - - -// Initialize the singleton instance. -await FoundryLocalManager.CreateAsync(config, Utils.GetAppLogger()); -var mgr = FoundryLocalManager.Instance; - - -// Ensure that any Execution Provider (EP) downloads run and are completed. -// Download and register all execution providers. -var currentEp = ""; -await mgr.DownloadAndRegisterEpsAsync((epName, percent) => -{ - if (epName != currentEp) - { - if (currentEp != "") Console.WriteLine(); - currentEp = epName; - } - Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%"); -}); -if (currentEp != "") Console.WriteLine(); -// - - -// -// 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"); -// Download the model (the method skips download if already cached) -await model.DownloadAsync(progress => -{ - Console.Write($"\rDownloading model: {progress:F2}%"); - if (progress >= 100f) - { - Console.WriteLine(); - } -}); - - -// 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(); -Console.WriteLine("done."); - -// <<<<<< OPEN AI SDK USAGE >>>>>> -// Use the OpenAI SDK to call the local Foundry web service - -ApiKeyCredential key = new ApiKeyCredential("notneeded"); -OpenAIClient client = new OpenAIClient(key, new OpenAIClientOptions -{ - Endpoint = new Uri(config.Web.Urls + "/v1"), -}); - -var chatClient = client.GetChatClient(model.Id); -var completionUpdates = chatClient.CompleteChatStreaming("Why is the sky blue?"); - -Console.Write($"[ASSISTANT]: "); -foreach (var completionUpdate in completionUpdates) -{ - if (completionUpdate.ContentUpdate.Count > 0) - { - Console.Write(completionUpdate.ContentUpdate[0].Text); - } -} -Console.WriteLine(); -// <<<<<< END OPEN AI SDK USAGE >>>>>> - -// Tidy up -// Stop the web service and unload model -await mgr.StopWebServiceAsync(); -await model.UnloadAsync(); -// -// \ No newline at end of file diff --git a/samples/cs/live-audio-transcription/README.md b/samples/cs/live-audio-transcription/README.md deleted file mode 100644 index 2e59eeb43..000000000 --- a/samples/cs/live-audio-transcription/README.md +++ /dev/null @@ -1,65 +0,0 @@ -# Live Audio Transcription Example - -Real-time microphone-to-text transcription using the Foundry Local C# SDK with Nemotron ASR. - -## Prerequisites - -- [Foundry Local](https://github.com/microsoft/Foundry-Local) installed -- .NET 9 SDK -- A microphone (optional — falls back to synthetic audio on non-Windows or with `--synth`) - -## Setup - -```bash -dotnet restore -``` - -> **Note:** Microphone capture uses [NAudio](https://github.com/naudio/NAudio) and is Windows-only. On other platforms, the sample falls back to synthetic audio for testing. - -## Run - -```bash -dotnet run -``` - -Speak into your microphone. Transcription appears in real-time (cyan text). Press `ENTER` to stop recording. - -To force synthetic audio (e.g., for CI or non-Windows): - -```bash -dotnet run -- --synth -``` - -## How it works - -1. Initializes the Foundry Local SDK and loads the Nemotron ASR model -2. Creates a `LiveAudioTranscriptionSession` with 16kHz/16-bit/mono PCM settings -3. Captures microphone audio via `NAudio.WaveInEvent` (or generates synthetic audio as fallback) -4. Pushes PCM chunks to the SDK via `session.AppendAsync()` through a bounded channel for backpressure -5. Reads transcription results via `await foreach (var result in session.GetStream())` -6. Access text via `result.Content[0].Text` (OpenAI Realtime ConversationItem pattern) - -## API - -```csharp -var audioClient = await model.GetAudioClientAsync(); -var session = audioClient.CreateLiveTranscriptionSession(); -session.Settings.SampleRate = 16000; -session.Settings.Channels = 1; -session.Settings.Language = "en"; - -await session.StartAsync(); - -// Push audio -await session.AppendAsync(pcmBytes); - -// Read results -await foreach (var result in session.GetStream()) -{ - Console.WriteLine(result.Content[0].Text); // transcribed text - Console.WriteLine(result.Content[0].Transcript); // alias (OpenAI compat) - Console.WriteLine(result.IsFinal); // true for final results -} - -await session.StopAsync(); -``` diff --git a/samples/cs/model-management-example/ModelManagementExample.csproj b/samples/cs/model-management-example/ModelManagementExample.csproj deleted file mode 100644 index 97cb8ef34..000000000 --- a/samples/cs/model-management-example/ModelManagementExample.csproj +++ /dev/null @@ -1,35 +0,0 @@ - - - - Exe - enable - enable - net9.0 - - - - $(NETCoreSdkRuntimeIdentifier) - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/cs/model-management-example/ModelManagementExample.sln b/samples/cs/model-management-example/ModelManagementExample.sln deleted file mode 100644 index f255391b2..000000000 --- a/samples/cs/model-management-example/ModelManagementExample.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModelManagementExample", "ModelManagementExample.csproj", "{9316B939-946C-4956-A4E7-9410017FD319}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {9316B939-946C-4956-A4E7-9410017FD319}.Debug|Any CPU.ActiveCfg = Debug|ARM64 - {9316B939-946C-4956-A4E7-9410017FD319}.Debug|Any CPU.Build.0 = Debug|ARM64 - {9316B939-946C-4956-A4E7-9410017FD319}.Debug|x64.ActiveCfg = Debug|x64 - {9316B939-946C-4956-A4E7-9410017FD319}.Debug|x64.Build.0 = Debug|x64 - {9316B939-946C-4956-A4E7-9410017FD319}.Debug|x86.ActiveCfg = Debug|ARM64 - {9316B939-946C-4956-A4E7-9410017FD319}.Debug|x86.Build.0 = Debug|ARM64 - {9316B939-946C-4956-A4E7-9410017FD319}.Release|Any CPU.ActiveCfg = Release|ARM64 - {9316B939-946C-4956-A4E7-9410017FD319}.Release|Any CPU.Build.0 = Release|ARM64 - {9316B939-946C-4956-A4E7-9410017FD319}.Release|x64.ActiveCfg = Release|x64 - {9316B939-946C-4956-A4E7-9410017FD319}.Release|x64.Build.0 = Release|x64 - {9316B939-946C-4956-A4E7-9410017FD319}.Release|x86.ActiveCfg = Release|ARM64 - {9316B939-946C-4956-A4E7-9410017FD319}.Release|x86.Build.0 = Release|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/samples/cs/model-management-example/Program.cs b/samples/cs/model-management-example/Program.cs deleted file mode 100644 index 76beb89ff..000000000 --- a/samples/cs/model-management-example/Program.cs +++ /dev/null @@ -1,155 +0,0 @@ -using Microsoft.AI.Foundry.Local; -using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels; -using System.Diagnostics; - -CancellationToken ct = new CancellationToken(); - -var config = new Configuration -{ - AppName = "foundry_local_samples", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information -}; - - -// Initialize the singleton instance. -await FoundryLocalManager.CreateAsync(config, Utils.GetAppLogger()); -var mgr = FoundryLocalManager.Instance; - - -// Download and register all execution providers. -var currentEp = ""; -await mgr.DownloadAndRegisterEpsAsync((epName, percent) => -{ - if (epName != currentEp) - { - if (currentEp != "") Console.WriteLine(); - currentEp = epName; - } - Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%"); -}); -if (currentEp != "") Console.WriteLine(); - - -// Model catalog operations -// In this section of the code we demonstrate the various model catalog operations -// Get the model catalog object -var catalog = await mgr.GetCatalogAsync(); - -// List available models -Console.WriteLine("Available models for your hardware:"); -var models = await catalog.ListModelsAsync(); -foreach (var availableModel in models) -{ - foreach (var variant in availableModel.Variants) - { - Console.WriteLine($" - Alias: {variant.Alias} (Id: {string.Join(", ", variant.Id)})"); - } -} - -// List cached models (i.e. downloaded models) from the catalog -var cachedModels = await catalog.GetCachedModelsAsync(); -Console.WriteLine("\nCached models:"); -foreach (var cachedModel in cachedModels) -{ - Console.WriteLine($"- {cachedModel.Alias} ({cachedModel.Id})"); -} - - -// Get a model using an alias from the catalog -var model = await catalog.GetModelAsync("qwen2.5-0.5b") ?? throw new Exception("Model not found"); - -// 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. -// If the selected variant is not the highest priority, it means that Foundry Local -// has found a locally cached variant for you to improve performance (remove need to download). -Console.WriteLine("\nThe default selected model variant is: " + model.Id); -if (model.Id != model.Variants.First().Id) -{ - Debug.Assert(await model.IsCachedAsync()); - Console.WriteLine("The model variant was selected due to being locally cached."); -} - - -// OPTIONAL: `model` can be used directly with its currently selected variant. -// You can explicitly select (`model.SelectVariant`) or use a specific variant from `model.Variants` -// if you want more control over the device and/or execution provider used. -// -// Choices: -// - Use a model variant 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 model variant from IModel.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. It would be equally valid to use `modelVariant` directly. -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 => -{ - Console.Write($"\rDownloading model: {progress:F2}%"); - if (progress >= 100f) - { - Console.WriteLine(); - } -}); - -// Load the model -await model.LoadAsync(); - - -// List loaded models (i.e. in memory) from the catalog -var loadedModels = await catalog.GetLoadedModelsAsync(); -Console.WriteLine("\nLoaded models:"); -foreach (var loadedModel in loadedModels) -{ - Console.WriteLine($"- {loadedModel.Alias} ({loadedModel.Id})"); -} -Console.WriteLine(); - - -// Get a chat client -var chatClient = await model.GetChatClientAsync(); - -// Create a chat message -List messages = new() -{ - new ChatMessage { Role = "user", Content = "Why is the sky blue?" } -}; - -// You can adjust settings on the chat client -chatClient.Settings.Temperature = 0.7f; -chatClient.Settings.MaxTokens = 512; - -Console.WriteLine("Chat completion response:"); -var streamingResponse = chatClient.CompleteChatStreamingAsync(messages, ct); -await foreach (var chunk in streamingResponse) -{ - Console.Write(chunk.Choices[0].Message.Content); - Console.Out.Flush(); -} -Console.WriteLine(); -Console.WriteLine(); - -// Tidy up - unload the model -Console.WriteLine($"Unloading model {model.Id}..."); -await model.UnloadAsync(); -Console.WriteLine("Model unloaded."); - -// Show loaded models from the catalog after unload -loadedModels = await catalog.GetLoadedModelsAsync(); -Console.WriteLine("\nLoaded models after unload (will be empty):"); -foreach (var loadedModel in loadedModels) -{ - Console.WriteLine($"- {loadedModel.Alias} ({loadedModel.Id})"); -} -Console.WriteLine(); -Console.WriteLine("Sample complete."); \ No newline at end of file diff --git a/samples/cs/native-chat-completions/NativeChatCompletions.csproj b/samples/cs/native-chat-completions/NativeChatCompletions.csproj deleted file mode 100644 index 97cb8ef34..000000000 --- a/samples/cs/native-chat-completions/NativeChatCompletions.csproj +++ /dev/null @@ -1,35 +0,0 @@ - - - - Exe - enable - enable - net9.0 - - - - $(NETCoreSdkRuntimeIdentifier) - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/cs/nuget.config b/samples/cs/nuget.config index 63954b2fb..534427902 100644 --- a/samples/cs/nuget.config +++ b/samples/cs/nuget.config @@ -2,18 +2,14 @@ + - - - - - - - \ No newline at end of file + diff --git a/samples/cs/foundry-local-web-server-responses-vision/Program.cs b/samples/cs/responses-api/Program.cs similarity index 100% rename from samples/cs/foundry-local-web-server-responses-vision/Program.cs rename to samples/cs/responses-api/Program.cs diff --git a/samples/cs/responses-api/README.md b/samples/cs/responses-api/README.md new file mode 100644 index 000000000..3ac706bc6 --- /dev/null +++ b/samples/cs/responses-api/README.md @@ -0,0 +1,46 @@ +# Vision via Web Server (Responses API) Example + +Stream a vision (image understanding) response from the local Foundry web server using the +OpenAI-compatible **Responses API** (`/v1/responses`). + +## Prerequisites + +- [Foundry Local](https://github.com/microsoft/Foundry-Local) installed +- .NET 9 SDK +- A vision-capable model (e.g. `qwen2.5-vl-3b`) + +## SDK consumption + +This sample tracks `main`: it consumes the Foundry Local C# SDK **from local source** via a +`ProjectReference` to `sdk/cs/src/Microsoft.AI.Foundry.Local.csproj`. It is **not** version-pinned +to a published package. The `Microsoft.AI.Foundry.Local.Core*` packages and native runtime assets +flow transitively from that project and restore from nuget.org. + +## Build & run + +```bash +# from this directory +dotnet build + +# describe the bundled test image with a vision model +dotnet run -- + +# describe your own image +dotnet run -- /path/to/image.jpg + +# list vision models in the catalog +dotnet run -- --list-models +``` + +`dotnet build` resolves the SDK from `sdk/cs` source via the project reference and restores +`Microsoft.AI.Foundry.Local.Core` from nuget.org. + +## What it does + +1. Initializes the SDK and downloads/registers execution providers. +2. Downloads and loads the requested vision model. +3. Starts the local web server. +4. Base64-encodes the image and POSTs a streaming request to `/v1/responses` with + `input_text` + `input_image` content parts. +5. Streams `response.output_text.delta` events to the console. +6. Stops the web server and unloads the model. diff --git a/samples/cs/audio-transcription-example/AudioTranscriptionExample.csproj b/samples/cs/responses-api/ResponsesApi.csproj similarity index 63% rename from samples/cs/audio-transcription-example/AudioTranscriptionExample.csproj rename to samples/cs/responses-api/ResponsesApi.csproj index ce8a65f04..4ee58566a 100644 --- a/samples/cs/audio-transcription-example/AudioTranscriptionExample.csproj +++ b/samples/cs/responses-api/ResponsesApi.csproj @@ -4,6 +4,9 @@ Exe enable enable + + + net9.0 @@ -11,14 +14,11 @@ $(NETCoreSdkRuntimeIdentifier) - - - - - - - - + + + @@ -27,9 +27,9 @@ - + - + PreserveNewest diff --git a/samples/cs/foundry-local-web-server-responses-vision/FoundryLocalWebServerResponsesVision.sln b/samples/cs/responses-api/ResponsesApi.sln similarity index 89% rename from samples/cs/foundry-local-web-server-responses-vision/FoundryLocalWebServerResponsesVision.sln rename to samples/cs/responses-api/ResponsesApi.sln index ac1df4ebb..185fb4009 100644 --- a/samples/cs/foundry-local-web-server-responses-vision/FoundryLocalWebServerResponsesVision.sln +++ b/samples/cs/responses-api/ResponsesApi.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.0.31903.59 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FoundryLocalWebServerResponsesVision", "FoundryLocalWebServerResponsesVision.csproj", "{8B4D2C97-2B5D-4A4E-9D31-7C8A6E6F3F11}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ResponsesApi", "ResponsesApi.csproj", "{8B4D2C97-2B5D-4A4E-9D31-7C8A6E6F3F11}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/samples/js/web-server-responses-vision-example/test_image.jpg b/samples/cs/responses-api/test_image.jpg similarity index 100% rename from samples/js/web-server-responses-vision-example/test_image.jpg rename to samples/cs/responses-api/test_image.jpg diff --git a/samples/cs/tool-calling-foundry-local-sdk/Program.cs b/samples/cs/tool-calling-foundry-local-sdk/Program.cs deleted file mode 100644 index a40742331..000000000 --- a/samples/cs/tool-calling-foundry-local-sdk/Program.cs +++ /dev/null @@ -1,179 +0,0 @@ -// -// -using Microsoft.AI.Foundry.Local; -using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels; -using Betalgo.Ranul.OpenAI.ObjectModels.ResponseModels; -using Betalgo.Ranul.OpenAI.ObjectModels.SharedModels; -using System.Text.Json; -// - -// -CancellationToken ct = new CancellationToken(); - -var config = new Configuration -{ - AppName = "foundry_local_samples", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information -}; - - -// Initialize the singleton instance. -await FoundryLocalManager.CreateAsync(config, Utils.GetAppLogger()); -var mgr = FoundryLocalManager.Instance; - - -// Ensure that any Execution Provider (EP) downloads run and are completed. -// Download and register all execution providers. -var currentEp = ""; -await mgr.DownloadAndRegisterEpsAsync((epName, percent) => -{ - if (epName != currentEp) - { - if (currentEp != "") Console.WriteLine(); - currentEp = epName; - } - Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%"); -}); -if (currentEp != "") Console.WriteLine(); -// - - -// -// 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"); - - -// Download the model (the method skips download if already cached) -await model.DownloadAsync(progress => -{ - Console.Write($"\rDownloading model: {progress:F2}%"); - if (progress >= 100f) - { - Console.WriteLine(); - } -}); - - -// Load the model -Console.Write($"Loading model {model.Id}..."); -await model.LoadAsync(); -Console.WriteLine("done."); -// - - -// Get a chat client -var chatClient = await model.GetChatClientAsync(); -chatClient.Settings.ToolChoice = ToolChoice.Required; // Force the model to make a tool call - - -// Prepare messages -List messages = -[ - new ChatMessage { Role = "system", Content = "You are a helpful AI assistant. If necessary, you can use any provided tools to answer the question." }, - new ChatMessage { Role = "user", Content = "What is the answer to 7 multiplied by 6?" } -]; - - -// -// Prepare tools -List tools = -[ - new ToolDefinition - { - Type = "function", - Function = new FunctionDefinition() - { - Name = "multiply_numbers", - Description = "A tool for multiplying two numbers.", - Parameters = new PropertyDefinition() - { - Type = "object", - Properties = new Dictionary() - { - { "first", new PropertyDefinition() { Type = "integer", Description = "The first number in the operation" } }, - { "second", new PropertyDefinition() { Type = "integer", Description = "The second number in the operation" } } - }, - Required = ["first", "second"] - } - } - } -]; -// - - -// -// Get a streaming chat completion response -var toolCallResponses = new List(); -Console.WriteLine("Chat completion response:"); -var streamingResponse = chatClient.CompleteChatStreamingAsync(messages, tools, ct); -await foreach (var chunk in streamingResponse) -{ - var content = chunk.Choices[0].Message.Content; - Console.Write(content); - Console.Out.Flush(); - - if (chunk.Choices[0].FinishReason == "tool_calls") - { - toolCallResponses.Add(chunk); - } -} -Console.WriteLine(); - - -// Invoke tools called and append responses to the chat -foreach (var chunk in toolCallResponses) -{ - var call = chunk?.Choices[0].Message.ToolCalls?[0].FunctionCall; - if (call?.Name == "multiply_numbers") - { - var arguments = JsonSerializer.Deserialize>(call.Arguments!)!; - var first = arguments["first"]; - var second = arguments["second"]; - - Console.WriteLine($"\nInvoking tool: {call?.Name} with arguments {first} and {second}"); - var result = Utils.MultiplyNumbers(first, second); - Console.WriteLine($"Tool response: {result.ToString()}"); - - var response = new ChatMessage - { - Role = "tool", - ToolCallId = chunk!.Choices[0].Message.ToolCalls![0].Id, - Content = result.ToString(), - }; - messages.Add(response); - } -} -Console.WriteLine("\nTool calls completed. Prompting model to continue conversation...\n"); - - -// Prompt the model to continue the conversation after the tool call -messages.Add(new ChatMessage { Role = "system", Content = "Respond only with the answer generated by the tool." }); - - -// Set tool calling back to auto so that the model can decide whether to call -// the tool again or continue the conversation based on the new user prompt -chatClient.Settings.ToolChoice = ToolChoice.Auto; - - -// Run the next turn of the conversation -Console.WriteLine("Chat completion response:"); -streamingResponse = chatClient.CompleteChatStreamingAsync(messages, tools, ct); -await foreach (var chunk in streamingResponse) -{ - var content = chunk.Choices[0].Message.Content; - Console.Write(content); - Console.Out.Flush(); -} -Console.WriteLine(); -// - - -// -// Tidy up - unload the model -await model.UnloadAsync(); -// -// \ No newline at end of file diff --git a/samples/cs/tool-calling-foundry-local-sdk/ToolCallingFoundryLocalSdk.csproj b/samples/cs/tool-calling-foundry-local-sdk/ToolCallingFoundryLocalSdk.csproj deleted file mode 100644 index 97cb8ef34..000000000 --- a/samples/cs/tool-calling-foundry-local-sdk/ToolCallingFoundryLocalSdk.csproj +++ /dev/null @@ -1,35 +0,0 @@ - - - - Exe - enable - enable - net9.0 - - - - $(NETCoreSdkRuntimeIdentifier) - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/cs/tool-calling-foundry-local-sdk/ToolCallingFoundryLocalSdk.sln b/samples/cs/tool-calling-foundry-local-sdk/ToolCallingFoundryLocalSdk.sln deleted file mode 100644 index adbf5ea23..000000000 --- a/samples/cs/tool-calling-foundry-local-sdk/ToolCallingFoundryLocalSdk.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ToolCallingFoundryLocalSdk", "ToolCallingFoundryLocalSdk.csproj", "{7B40637D-D7E3-4A95-9B57-8D0EF84C8532}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Debug|Any CPU.ActiveCfg = Debug|ARM64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Debug|Any CPU.Build.0 = Debug|ARM64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Debug|x64.ActiveCfg = Debug|x64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Debug|x64.Build.0 = Debug|x64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Debug|x86.ActiveCfg = Debug|ARM64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Debug|x86.Build.0 = Debug|ARM64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Release|Any CPU.ActiveCfg = Release|ARM64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Release|Any CPU.Build.0 = Release|ARM64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Release|x64.ActiveCfg = Release|x64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Release|x64.Build.0 = Release|x64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Release|x86.ActiveCfg = Release|ARM64 - {7B40637D-D7E3-4A95-9B57-8D0EF84C8532}.Release|x86.Build.0 = Release|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/samples/cs/tool-calling-foundry-local-web-server/Program.cs b/samples/cs/tool-calling-foundry-local-web-server/Program.cs deleted file mode 100644 index 6644a438b..000000000 --- a/samples/cs/tool-calling-foundry-local-web-server/Program.cs +++ /dev/null @@ -1,190 +0,0 @@ -// -using Microsoft.AI.Foundry.Local; -using OpenAI; -using OpenAI.Chat; -using System.ClientModel; -using System.Text.Json; - -var config = new Configuration -{ - AppName = "foundry_local_samples", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information, - Web = new Configuration.WebService - { - Urls = "http://127.0.0.1:52495" - } -}; - - -// Initialize the singleton instance. -await FoundryLocalManager.CreateAsync(config, Utils.GetAppLogger()); -var mgr = FoundryLocalManager.Instance; - - -// Download and register all execution providers. -var currentEp = ""; -await mgr.DownloadAndRegisterEpsAsync((epName, percent) => -{ - if (epName != currentEp) - { - if (currentEp != "") Console.WriteLine(); - currentEp = epName; - } - Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%"); -}); -if (currentEp != "") Console.WriteLine(); - - -// 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"); -// Download the model (the method skips download if already cached) -await model.DownloadAsync(progress => -{ - Console.Write($"\rDownloading model: {progress:F2}%"); - if (progress >= 100f) - { - Console.WriteLine(); - } -}); - - -// 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(); -Console.WriteLine("done."); - - -// <<<<<< OPEN AI SDK USAGE >>>>>> -// Use the OpenAI SDK to call the local Foundry web service - -ApiKeyCredential key = new ApiKeyCredential("notneeded"); -OpenAIClient client = new OpenAIClient(key, new OpenAIClientOptions -{ - Endpoint = new Uri(config.Web.Urls + "/v1"), -}); - - -// Get chat client -var chatClient = client.GetChatClient(model.Id); - - -// Prepare messages -var messages = new List -{ - ChatMessage.CreateSystemMessage("You are a helpful AI assistant. If necessary, you can use any provided tools to answer the question."), - ChatMessage.CreateUserMessage("What is the answer to 7 multiplied by 6?") -}; - - -// Prepare tools -var tools = new List -{ - ChatTool.CreateFunctionTool( - functionName: "multiply_numbers", - functionDescription: "A tool for multiplying two numbers.", - functionParameters: BinaryData.FromString(""" - { - "type": "object", - "properties": { - "first": { "type": "number", "description": "The first number in the operation" }, - "second": { "type": "number", "description": "The second number in the operation" } - }, - "required": ["first", "second"] - } - """) - ) -}; - - -// Prepare chat completion options -var options = new ChatCompletionOptions -{ - ToolChoice = ChatToolChoice.CreateRequiredChoice() // Force the model to make a tool call -}; -foreach (var tool in tools) -{ - options.Tools.Add(tool); -} - - -// Get a streaming chat completion response -var completionUpdates = chatClient.CompleteChatStreaming(messages, options); -var toolCalls = new List(); -Console.Write($"[ASSISTANT]: "); -foreach (var completionUpdate in completionUpdates) -{ - if (completionUpdate.ContentUpdate.Count > 0) - { - Console.Write(completionUpdate.ContentUpdate[0].Text); - } - - if (completionUpdate.FinishReason == ChatFinishReason.ToolCalls) - { - foreach (var toolCall in completionUpdate.ToolCallUpdates) - { - toolCalls.Add(toolCall); - } - } -} -Console.WriteLine(); - - -// Invoke tools called and append responses to the chat -foreach (var toolCall in toolCalls) -{ - if (toolCall.FunctionName == "multiply_numbers") - { - var arguments = JsonDocument.Parse(toolCall.FunctionArgumentsUpdate.ToString()).RootElement; - var first = arguments.GetProperty("first").GetInt32(); - var second = arguments.GetProperty("second").GetInt32(); - - Console.WriteLine($"\nInvoking tool: {toolCall.FunctionName} with arguments {first} and {second}"); - var result = Utils.MultiplyNumbers(first, second); - Console.WriteLine($"Tool response: {result.ToString()}"); - - messages.Add(ChatMessage.CreateToolMessage(toolCallId: "abcd1234", content: result.ToString())); - } -} -Console.WriteLine("\nTool calls completed. Prompting model to continue conversation...\n"); - - -// Prompt the model to continue the conversation after the tool call -messages.Add(ChatMessage.CreateSystemMessage("Respond only with the answer generated by the tool.")); - - -// Set tool calling back to auto so that the model can decide whether to call -// the tool again or continue the conversation based on the new user prompt -options.ToolChoice = ChatToolChoice.CreateAutoChoice(); - - -// Run the next turn of the conversation -Console.WriteLine("Chat completion response:"); -completionUpdates = chatClient.CompleteChatStreaming(messages, options); -Console.Write($"[ASSISTANT]: "); -foreach (var completionUpdate in completionUpdates) -{ - if (completionUpdate.ContentUpdate.Count > 0) - { - Console.Write(completionUpdate.ContentUpdate[0].Text); - } -} -Console.WriteLine(); - -// <<<<<< END OPEN AI SDK USAGE >>>>>> - - -// Tidy up -// Stop the web service and unload model -await mgr.StopWebServiceAsync(); -await model.UnloadAsync(); -// \ No newline at end of file diff --git a/samples/cs/tool-calling-foundry-local-web-server/ToolCallingFoundryLocalWebServer.sln b/samples/cs/tool-calling-foundry-local-web-server/ToolCallingFoundryLocalWebServer.sln deleted file mode 100644 index 7d1568e18..000000000 --- a/samples/cs/tool-calling-foundry-local-web-server/ToolCallingFoundryLocalWebServer.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ToolCallingFoundryLocalWebServer", "ToolCallingFoundryLocalWebServer.csproj", "{F9BD2479-A235-4BBF-A722-DF180A076143}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F9BD2479-A235-4BBF-A722-DF180A076143}.Debug|Any CPU.ActiveCfg = Debug|ARM64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Debug|Any CPU.Build.0 = Debug|ARM64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Debug|x64.ActiveCfg = Debug|x64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Debug|x64.Build.0 = Debug|x64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Debug|x86.ActiveCfg = Debug|ARM64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Debug|x86.Build.0 = Debug|ARM64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Release|Any CPU.ActiveCfg = Release|ARM64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Release|Any CPU.Build.0 = Release|ARM64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Release|x64.ActiveCfg = Release|x64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Release|x64.Build.0 = Release|x64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Release|x86.ActiveCfg = Release|ARM64 - {F9BD2479-A235-4BBF-A722-DF180A076143}.Release|x86.Build.0 = Release|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/samples/cs/tutorial-chat-assistant/Program.cs b/samples/cs/tutorial-chat-assistant/Program.cs deleted file mode 100644 index d06de6a5e..000000000 --- a/samples/cs/tutorial-chat-assistant/Program.cs +++ /dev/null @@ -1,114 +0,0 @@ -// -// -using Microsoft.AI.Foundry.Local; -using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels; -using Microsoft.Extensions.Logging; -// - -// -CancellationToken ct = CancellationToken.None; - -var config = new Configuration -{ - AppName = "foundry_local_samples", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information -}; - -using var loggerFactory = LoggerFactory.Create(builder => -{ - builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information); -}); -var logger = loggerFactory.CreateLogger(); - -// Initialize the singleton instance -await FoundryLocalManager.CreateAsync(config, logger); -var mgr = FoundryLocalManager.Instance; - -// Download and register all execution providers. -var currentEp = ""; -await mgr.DownloadAndRegisterEpsAsync((epName, percent) => -{ - if (epName != currentEp) - { - if (currentEp != "") Console.WriteLine(); - currentEp = epName; - } - Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%"); -}); -if (currentEp != "") Console.WriteLine(); - -// Select and load a model from the catalog -var catalog = await mgr.GetCatalogAsync(); -var model = await catalog.GetModelAsync("qwen2.5-0.5b") - ?? throw new Exception("Model not found"); - -await model.DownloadAsync(progress => -{ - Console.Write($"\rDownloading model: {progress:F2}%"); - if (progress >= 100f) Console.WriteLine(); -}); - -await model.LoadAsync(); -Console.WriteLine("Model loaded and ready."); - -// Get a chat client -var chatClient = await model.GetChatClientAsync(); -// - -// -// Start the conversation with a system prompt -var messages = new List -{ - new ChatMessage - { - Role = "system", - Content = "You are a helpful, friendly assistant. Keep your responses " + - "concise and conversational. If you don't know something, say so." - } -}; -// - -Console.WriteLine("\nChat assistant ready! Type 'quit' to exit.\n"); - -// -while (true) -{ - Console.Write("You: "); - var userInput = Console.ReadLine(); - if (string.IsNullOrWhiteSpace(userInput) || - userInput.Equals("quit", StringComparison.OrdinalIgnoreCase) || - userInput.Equals("exit", StringComparison.OrdinalIgnoreCase)) - { - break; - } - - // Add the user's message to conversation history - messages.Add(new ChatMessage { Role = "user", Content = userInput }); - - // - // Stream the response token by token - Console.Write("Assistant: "); - var fullResponse = string.Empty; - var streamingResponse = chatClient.CompleteChatStreamingAsync(messages, ct); - await foreach (var chunk in streamingResponse) - { - var content = chunk.Choices[0].Message.Content; - if (!string.IsNullOrEmpty(content)) - { - Console.Write(content); - Console.Out.Flush(); - fullResponse += content; - } - } - Console.WriteLine("\n"); - // - - // Add the complete response to conversation history - messages.Add(new ChatMessage { Role = "assistant", Content = fullResponse }); -} -// - -// Clean up - unload the model -await model.UnloadAsync(); -Console.WriteLine("Model unloaded. Goodbye!"); -// diff --git a/samples/cs/tutorial-chat-assistant/TutorialChatAssistant.csproj b/samples/cs/tutorial-chat-assistant/TutorialChatAssistant.csproj deleted file mode 100644 index fcc9257da..000000000 --- a/samples/cs/tutorial-chat-assistant/TutorialChatAssistant.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - Exe - enable - enable - net9.0 - - - - $(NETCoreSdkRuntimeIdentifier) - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/cs/tutorial-chat-assistant/TutorialChatAssistant.sln b/samples/cs/tutorial-chat-assistant/TutorialChatAssistant.sln deleted file mode 100644 index a9c77e164..000000000 --- a/samples/cs/tutorial-chat-assistant/TutorialChatAssistant.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TutorialChatAssistant", "TutorialChatAssistant.csproj", "{5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Debug|Any CPU.ActiveCfg = Debug|ARM64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Debug|Any CPU.Build.0 = Debug|ARM64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Debug|x64.ActiveCfg = Debug|x64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Debug|x64.Build.0 = Debug|x64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Debug|x86.ActiveCfg = Debug|ARM64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Debug|x86.Build.0 = Debug|ARM64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Release|Any CPU.ActiveCfg = Release|ARM64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Release|Any CPU.Build.0 = Release|ARM64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Release|x64.ActiveCfg = Release|x64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Release|x64.Build.0 = Release|x64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Release|x86.ActiveCfg = Release|ARM64 - {5D5778BD-B40A-4D9E-BC2F-65AD50EE6F94}.Release|x86.Build.0 = Release|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/samples/cs/tutorial-document-summarizer/Program.cs b/samples/cs/tutorial-document-summarizer/Program.cs deleted file mode 100644 index 333d5c964..000000000 --- a/samples/cs/tutorial-document-summarizer/Program.cs +++ /dev/null @@ -1,122 +0,0 @@ -// -// -using Microsoft.AI.Foundry.Local; -using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels; -using Microsoft.Extensions.Logging; -// - -// -CancellationToken ct = CancellationToken.None; - -var config = new Configuration -{ - AppName = "foundry_local_samples", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information -}; - -using var loggerFactory = LoggerFactory.Create(builder => -{ - builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information); -}); -var logger = loggerFactory.CreateLogger(); - -// Initialize the singleton instance -await FoundryLocalManager.CreateAsync(config, logger); -var mgr = FoundryLocalManager.Instance; - -// Download and register all execution providers. -var currentEp = ""; -await mgr.DownloadAndRegisterEpsAsync((epName, percent) => -{ - if (epName != currentEp) - { - if (currentEp != "") Console.WriteLine(); - currentEp = epName; - } - Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%"); -}); -if (currentEp != "") Console.WriteLine(); - -// Select and load a model from the catalog -var catalog = await mgr.GetCatalogAsync(); -var model = await catalog.GetModelAsync("qwen2.5-0.5b") - ?? throw new Exception("Model not found"); - -await model.DownloadAsync(progress => -{ - Console.Write($"\rDownloading model: {progress:F2}%"); - if (progress >= 100f) Console.WriteLine(); -}); - -await model.LoadAsync(); -Console.WriteLine("Model loaded and ready.\n"); - -// Get a chat client -var chatClient = await model.GetChatClientAsync(); -// - -// -var systemPrompt = - "Summarize the following document into concise bullet points. " + - "Focus on the key points and main ideas."; - -// -var target = args.Length > 0 ? args[0] : "document.txt"; -// - -if (Directory.Exists(target)) -{ - await SummarizeDirectoryAsync(chatClient, target, systemPrompt, ct); -} -else -{ - Console.WriteLine($"--- {Path.GetFileName(target)} ---"); - await SummarizeFileAsync(chatClient, target, systemPrompt, ct); -} -// - -// Clean up -await model.UnloadAsync(); -Console.WriteLine("\nModel unloaded. Done!"); - -async Task SummarizeFileAsync( - dynamic client, - string filePath, - string prompt, - CancellationToken token) -{ - var fileContent = await File.ReadAllTextAsync(filePath, token); - var messages = new List - { - new ChatMessage { Role = "system", Content = prompt }, - new ChatMessage { Role = "user", Content = fileContent } - }; - - var response = await client.CompleteChatAsync(messages, token); - Console.WriteLine(response.Choices[0].Message.Content); -} - -async Task SummarizeDirectoryAsync( - dynamic client, - string directory, - string prompt, - CancellationToken token) -{ - var txtFiles = Directory.GetFiles(directory, "*.txt") - .OrderBy(f => f) - .ToArray(); - - if (txtFiles.Length == 0) - { - Console.WriteLine($"No .txt files found in {directory}"); - return; - } - - foreach (var txtFile in txtFiles) - { - Console.WriteLine($"--- {Path.GetFileName(txtFile)} ---"); - await SummarizeFileAsync(client, txtFile, prompt, token); - Console.WriteLine(); - } -} -// diff --git a/samples/cs/tutorial-document-summarizer/TutorialDocumentSummarizer.csproj b/samples/cs/tutorial-document-summarizer/TutorialDocumentSummarizer.csproj deleted file mode 100644 index fcc9257da..000000000 --- a/samples/cs/tutorial-document-summarizer/TutorialDocumentSummarizer.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - Exe - enable - enable - net9.0 - - - - $(NETCoreSdkRuntimeIdentifier) - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/cs/tutorial-document-summarizer/TutorialDocumentSummarizer.sln b/samples/cs/tutorial-document-summarizer/TutorialDocumentSummarizer.sln deleted file mode 100644 index 7d7a0fc99..000000000 --- a/samples/cs/tutorial-document-summarizer/TutorialDocumentSummarizer.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TutorialDocumentSummarizer", "TutorialDocumentSummarizer.csproj", "{6868D03F-BD8E-46ED-9A5B-95346A3810A4}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Debug|Any CPU.ActiveCfg = Debug|ARM64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Debug|Any CPU.Build.0 = Debug|ARM64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Debug|x64.ActiveCfg = Debug|x64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Debug|x64.Build.0 = Debug|x64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Debug|x86.ActiveCfg = Debug|ARM64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Debug|x86.Build.0 = Debug|ARM64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Release|Any CPU.ActiveCfg = Release|ARM64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Release|Any CPU.Build.0 = Release|ARM64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Release|x64.ActiveCfg = Release|x64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Release|x64.Build.0 = Release|x64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Release|x86.ActiveCfg = Release|ARM64 - {6868D03F-BD8E-46ED-9A5B-95346A3810A4}.Release|x86.Build.0 = Release|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/samples/cs/tutorial-tool-calling/Program.cs b/samples/cs/tutorial-tool-calling/Program.cs deleted file mode 100644 index 5ae60419a..000000000 --- a/samples/cs/tutorial-tool-calling/Program.cs +++ /dev/null @@ -1,241 +0,0 @@ -// -// -using System.Text.Json; -using Microsoft.AI.Foundry.Local; -using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels; -using Betalgo.Ranul.OpenAI.ObjectModels.ResponseModels; -using Betalgo.Ranul.OpenAI.ObjectModels.SharedModels; -using Microsoft.Extensions.Logging; -// - -CancellationToken ct = CancellationToken.None; - -// -// --- Tool definitions --- -List tools = -[ - new ToolDefinition - { - Type = "function", - Function = new FunctionDefinition() - { - Name = "get_weather", - Description = "Get the current weather for a location", - Parameters = new PropertyDefinition() - { - Type = "object", - Properties = new Dictionary() - { - { "location", new PropertyDefinition() { Type = "string", Description = "The city or location" } }, - { "unit", new PropertyDefinition() { Type = "string", Description = "Temperature unit (celsius or fahrenheit)" } } - }, - Required = ["location"] - } - } - }, - new ToolDefinition - { - Type = "function", - Function = new FunctionDefinition() - { - Name = "calculate", - Description = "Perform a math calculation", - Parameters = new PropertyDefinition() - { - Type = "object", - Properties = new Dictionary() - { - { "expression", new PropertyDefinition() { Type = "string", Description = "The math expression to evaluate" } } - }, - Required = ["expression"] - } - } - } -]; - -// --- Tool implementations --- -string ExecuteTool(string functionName, JsonElement arguments) -{ - switch (functionName) - { - case "get_weather": - var location = arguments.GetProperty("location") - .GetString() ?? "unknown"; - var unit = arguments.TryGetProperty("unit", out var u) - ? u.GetString() ?? "celsius" - : "celsius"; - var temp = unit == "celsius" ? 22 : 72; - return JsonSerializer.Serialize(new - { - location, - temperature = temp, - unit, - condition = "Sunny" - }); - - case "calculate": - var expression = arguments.GetProperty("expression") - .GetString() ?? ""; - try - { - var result = new System.Data.DataTable() - .Compute(expression, null); - return JsonSerializer.Serialize(new - { - expression, - result = result?.ToString() - }); - } - catch (Exception ex) - { - return JsonSerializer.Serialize(new - { - error = ex.Message - }); - } - - default: - return JsonSerializer.Serialize(new - { - error = $"Unknown function: {functionName}" - }); - } -} -// - -// -// --- Main application --- -var config = new Configuration -{ - AppName = "foundry_local_samples", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information -}; - -using var loggerFactory = LoggerFactory.Create(builder => -{ - builder.SetMinimumLevel( - Microsoft.Extensions.Logging.LogLevel.Information - ); -}); -var logger = loggerFactory.CreateLogger(); - -await FoundryLocalManager.CreateAsync(config, logger); -var mgr = FoundryLocalManager.Instance; - -// Download and register all execution providers. -var currentEp = ""; -await mgr.DownloadAndRegisterEpsAsync((epName, percent) => -{ - if (epName != currentEp) - { - if (currentEp != "") Console.WriteLine(); - currentEp = epName; - } - Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%"); -}); -if (currentEp != "") Console.WriteLine(); - -var catalog = await mgr.GetCatalogAsync(); -var model = await catalog.GetModelAsync("qwen2.5-0.5b") - ?? throw new Exception("Model not found"); - -await model.DownloadAsync(progress => -{ - Console.Write($"\rDownloading model: {progress:F2}%"); - if (progress >= 100f) Console.WriteLine(); -}); - -await model.LoadAsync(); -Console.WriteLine("Model loaded and ready."); - -var chatClient = await model.GetChatClientAsync(); -chatClient.Settings.ToolChoice = ToolChoice.Auto; - -var messages = new List -{ - new ChatMessage - { - Role = "system", - Content = "You are a helpful assistant with access to tools. " + - "Use them when needed to answer questions accurately." - } -}; -// - -// -Console.WriteLine("\nTool-calling assistant ready! Type 'quit' to exit.\n"); - -while (true) -{ - Console.Write("You: "); - var userInput = Console.ReadLine(); - if (string.IsNullOrWhiteSpace(userInput) || - userInput.Equals("quit", StringComparison.OrdinalIgnoreCase) || - userInput.Equals("exit", StringComparison.OrdinalIgnoreCase)) - { - break; - } - - messages.Add(new ChatMessage - { - Role = "user", - Content = userInput - }); - - var response = await chatClient.CompleteChatAsync( - messages, tools, ct - ); - - var choice = response.Choices[0].Message; - - if (choice.ToolCalls is { Count: > 0 }) - { - messages.Add(choice); - - foreach (var toolCall in choice.ToolCalls) - { - var toolArgs = JsonDocument.Parse( - toolCall.FunctionCall.Arguments - ).RootElement; - Console.WriteLine( - $" Tool call: {toolCall.FunctionCall.Name}({toolArgs})" - ); - - var result = ExecuteTool( - toolCall.FunctionCall.Name, toolArgs - ); - messages.Add(new ChatMessage - { - Role = "tool", - ToolCallId = toolCall.Id, - Content = result - }); - } - - var finalResponse = await chatClient.CompleteChatAsync( - messages, tools, ct - ); - var answer = finalResponse.Choices[0].Message.Content ?? ""; - messages.Add(new ChatMessage - { - Role = "assistant", - Content = answer - }); - Console.WriteLine($"Assistant: {answer}\n"); - } - else - { - var answer = choice.Content ?? ""; - messages.Add(new ChatMessage - { - Role = "assistant", - Content = answer - }); - Console.WriteLine($"Assistant: {answer}\n"); - } -} - -await model.UnloadAsync(); -Console.WriteLine("Model unloaded. Goodbye!"); -// -// diff --git a/samples/cs/tutorial-tool-calling/TutorialToolCalling.csproj b/samples/cs/tutorial-tool-calling/TutorialToolCalling.csproj deleted file mode 100644 index fcc9257da..000000000 --- a/samples/cs/tutorial-tool-calling/TutorialToolCalling.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - Exe - enable - enable - net9.0 - - - - $(NETCoreSdkRuntimeIdentifier) - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/cs/tutorial-tool-calling/TutorialToolCalling.sln b/samples/cs/tutorial-tool-calling/TutorialToolCalling.sln deleted file mode 100644 index 6a86331bb..000000000 --- a/samples/cs/tutorial-tool-calling/TutorialToolCalling.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TutorialToolCalling", "TutorialToolCalling.csproj", "{155923AB-A0C6-447D-A46A-7C8318D31596}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {155923AB-A0C6-447D-A46A-7C8318D31596}.Debug|Any CPU.ActiveCfg = Debug|ARM64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Debug|Any CPU.Build.0 = Debug|ARM64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Debug|x64.ActiveCfg = Debug|x64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Debug|x64.Build.0 = Debug|x64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Debug|x86.ActiveCfg = Debug|ARM64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Debug|x86.Build.0 = Debug|ARM64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Release|Any CPU.ActiveCfg = Release|ARM64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Release|Any CPU.Build.0 = Release|ARM64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Release|x64.ActiveCfg = Release|x64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Release|x64.Build.0 = Release|x64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Release|x86.ActiveCfg = Release|ARM64 - {155923AB-A0C6-447D-A46A-7C8318D31596}.Release|x86.Build.0 = Release|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/samples/cs/tutorial-voice-to-text/Program.cs b/samples/cs/tutorial-voice-to-text/Program.cs deleted file mode 100644 index 9a1a36c33..000000000 --- a/samples/cs/tutorial-voice-to-text/Program.cs +++ /dev/null @@ -1,118 +0,0 @@ -// -// -using Microsoft.AI.Foundry.Local; -using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels; -using Microsoft.Extensions.Logging; -using System.Text; -// - -// -CancellationToken ct = CancellationToken.None; - -var config = new Configuration -{ - AppName = "foundry_local_samples", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information -}; - -using var loggerFactory = LoggerFactory.Create(builder => -{ - builder.SetMinimumLevel( - Microsoft.Extensions.Logging.LogLevel.Information - ); -}); -var logger = loggerFactory.CreateLogger(); - -// Initialize the singleton instance -await FoundryLocalManager.CreateAsync(config, logger); -var mgr = FoundryLocalManager.Instance; - -// Download and register all execution providers. -var currentEp = ""; -await mgr.DownloadAndRegisterEpsAsync((epName, percent) => -{ - if (epName != currentEp) - { - if (currentEp != "") Console.WriteLine(); - currentEp = epName; - } - Console.Write($"\r {epName.PadRight(30)} {percent,6:F1}%"); -}); -if (currentEp != "") Console.WriteLine(); - -var catalog = await mgr.GetCatalogAsync(); -// - -// -// Load the speech-to-text model -var speechModel = await catalog.GetModelAsync("whisper-tiny") - ?? throw new Exception("Speech model not found"); - -await speechModel.DownloadAsync(progress => -{ - Console.Write($"\rDownloading speech model: {progress:F2}%"); - if (progress >= 100f) Console.WriteLine(); -}); - -await speechModel.LoadAsync(); -Console.WriteLine("Speech model loaded."); - -// Transcribe the audio file -var audioClient = await speechModel.GetAudioClientAsync(); -var transcriptionText = new StringBuilder(); - -Console.WriteLine("\nTranscription:"); -var audioResponse = audioClient - .TranscribeAudioStreamingAsync("meeting-notes.wav", ct); -await foreach (var chunk in audioResponse) -{ - Console.Write(chunk.Text); - transcriptionText.Append(chunk.Text); -} -Console.WriteLine(); - -// Unload the speech model to free memory -await speechModel.UnloadAsync(); -// - -// -// Load the chat model for summarization -var chatModel = await catalog.GetModelAsync("qwen2.5-0.5b") - ?? throw new Exception("Chat model not found"); - -await chatModel.DownloadAsync(progress => -{ - Console.Write($"\rDownloading chat model: {progress:F2}%"); - if (progress >= 100f) Console.WriteLine(); -}); - -await chatModel.LoadAsync(); -Console.WriteLine("Chat model loaded."); - -// Summarize the transcription into organized notes -var chatClient = await chatModel.GetChatClientAsync(); -var messages = new List -{ - new ChatMessage - { - Role = "system", - Content = "You are a note-taking assistant. Summarize " + - "the following transcription into organized, " + - "concise notes with bullet points." - }, - new ChatMessage - { - Role = "user", - Content = transcriptionText.ToString() - } -}; - -var chatResponse = await chatClient.CompleteChatAsync(messages, ct); -var summary = chatResponse.Choices[0].Message.Content; -Console.WriteLine($"\nSummary:\n{summary}"); - -// Clean up -await chatModel.UnloadAsync(); -Console.WriteLine("\nDone. Models unloaded."); -// -// diff --git a/samples/cs/tutorial-voice-to-text/TutorialVoiceToText.csproj b/samples/cs/tutorial-voice-to-text/TutorialVoiceToText.csproj deleted file mode 100644 index fcc9257da..000000000 --- a/samples/cs/tutorial-voice-to-text/TutorialVoiceToText.csproj +++ /dev/null @@ -1,37 +0,0 @@ - - - - Exe - enable - enable - net9.0 - - - - $(NETCoreSdkRuntimeIdentifier) - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/cs/tutorial-voice-to-text/TutorialVoiceToText.sln b/samples/cs/tutorial-voice-to-text/TutorialVoiceToText.sln deleted file mode 100644 index ae2a2b396..000000000 --- a/samples/cs/tutorial-voice-to-text/TutorialVoiceToText.sln +++ /dev/null @@ -1,34 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TutorialVoiceToText", "TutorialVoiceToText.csproj", "{C12663C3-AB3F-4652-BC43-A92E43602ACC}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|x64 = Debug|x64 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|x64 = Release|x64 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Debug|Any CPU.ActiveCfg = Debug|ARM64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Debug|Any CPU.Build.0 = Debug|ARM64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Debug|x64.ActiveCfg = Debug|x64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Debug|x64.Build.0 = Debug|x64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Debug|x86.ActiveCfg = Debug|ARM64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Debug|x86.Build.0 = Debug|ARM64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Release|Any CPU.ActiveCfg = Release|ARM64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Release|Any CPU.Build.0 = Release|ARM64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Release|x64.ActiveCfg = Release|x64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Release|x64.Build.0 = Release|x64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Release|x86.ActiveCfg = Release|ARM64 - {C12663C3-AB3F-4652-BC43-A92E43602ACC}.Release|x86.Build.0 = Release|ARM64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/samples/cs/verify-winml/Program.cs b/samples/cs/verify-winml/Program.cs deleted file mode 100644 index 27a141296..000000000 --- a/samples/cs/verify-winml/Program.cs +++ /dev/null @@ -1,278 +0,0 @@ -/// -/// Foundry Local SDK - WinML 2.0 EP Verification (C#) -/// -/// Verifies: -/// 1. Execution providers are discovered and registered -/// 2. Accelerated models appear in catalog after EP registration -/// 3. Streaming chat completions work on an accelerated model -/// - -using Microsoft.AI.Foundry.Local; -using Microsoft.Extensions.Logging; -using Betalgo.Ranul.OpenAI.ObjectModels.RequestModels; - -const string PASS = "\x1b[92m[PASS]\x1b[0m"; -const string FAIL = "\x1b[91m[FAIL]\x1b[0m"; -const string INFO = "\x1b[94m[INFO]\x1b[0m"; -const string WARN = "\x1b[93m[WARN]\x1b[0m"; - -var results = new List<(string Name, bool Passed)>(); - -void LogResult(string testName, bool passed, string detail = "") -{ - var status = passed ? PASS : FAIL; - var msg = string.IsNullOrEmpty(detail) ? $"{status} {testName}" : $"{status} {testName} - {detail}"; - Console.WriteLine(msg); - results.Add((testName, passed)); -} - -void PrintSeparator(string title) -{ - Console.WriteLine($"\n{new string('=', 60)}"); - Console.WriteLine($" {title}"); - Console.WriteLine($"{new string('=', 60)}\n"); -} - -void PrintSummary() -{ - PrintSeparator("Summary"); - var passed = results.Count(r => r.Passed); - foreach (var (name, p) in results) - { - Console.WriteLine($" {(p ? "✓" : "✗")} {name}"); - } - - Console.WriteLine($"\n {passed}/{results.Count} tests passed"); -} - -bool IsAcceleratedVariant(IModel model) -{ - var runtime = model.Info?.Runtime; - return runtime != null && (runtime.DeviceType == DeviceType.GPU || runtime.DeviceType == DeviceType.NPU); -} - -CancellationToken ct = CancellationToken.None; - -// ── 0. Initialize FoundryLocalManager ────────────────────── -PrintSeparator("Initialization"); -var config = new Configuration -{ - AppName = "verify_winml", - LogLevel = Microsoft.AI.Foundry.Local.LogLevel.Information -}; - -using var loggerFactory = LoggerFactory.Create(builder => - builder.SetMinimumLevel(Microsoft.Extensions.Logging.LogLevel.Information)); -var logger = loggerFactory.CreateLogger(); - -await FoundryLocalManager.CreateAsync(config, logger); -var mgr = FoundryLocalManager.Instance; -Console.WriteLine($"{INFO} FoundryLocalManager initialized."); - -// ── 1. Discover & Register EPs ──────────────────────────── -PrintSeparator("Step 1: Discover & Register Execution Providers"); -EpInfo[] eps = []; -try -{ - eps = mgr.DiscoverEps(); - Console.WriteLine($"{INFO} Discovered {eps.Length} execution providers:"); - foreach (var ep in eps) - { - Console.WriteLine($" - {ep.Name,-40} Registered: {ep.IsRegistered}"); - } - - LogResult("EP Discovery", true, $"{eps.Length} EP(s) found"); -} -catch (Exception e) -{ - LogResult("EP Discovery", false, e.Message); -} - -if (eps.Length == 0) -{ - var detail = "No execution providers discovered on this machine"; - LogResult("EP Download & Registration", false, detail); - Console.WriteLine($"\n{FAIL} {detail}."); - PrintSummary(); - return; -} - -try -{ - string? currentProgressEp = null; - var currentProgressPercent = -1d; - - var epResult = await mgr.DownloadAndRegisterEpsAsync( - new Action((epName, percent) => - { - if (currentProgressEp != null && - (!epName.Equals(currentProgressEp, StringComparison.OrdinalIgnoreCase) || percent < currentProgressPercent)) - { - Console.WriteLine(); - } - - currentProgressEp = epName; - currentProgressPercent = percent; - Console.Write($"\r Downloading {epName}: {percent:F1}%"); - }), - ct); - - if (currentProgressEp != null) - { - Console.WriteLine(); - } - - Console.WriteLine($"{INFO} EP registration: success={epResult.Success}, status={epResult.Status}"); - if (epResult.RegisteredEps?.Any() == true) - { - Console.WriteLine($" Registered: {string.Join(", ", epResult.RegisteredEps)}"); - } - - if (epResult.FailedEps?.Any() == true) - { - Console.WriteLine($" Failed: {string.Join(", ", epResult.FailedEps)}"); - } - - var downloadOk = epResult.Success; - var detail = downloadOk && epResult.RegisteredEps?.Any() == true - ? $"{epResult.RegisteredEps.Length} EP(s) registered" - : epResult.Status; - LogResult("EP Download & Registration", downloadOk, detail); - if (!downloadOk) - { - PrintSummary(); - return; - } -} -catch (Exception e) -{ - Console.WriteLine(); - LogResult("EP Download & Registration", false, e.Message); - PrintSummary(); - return; -} - -// ── 2. List Models & Find Accelerated Variants ──────────── -PrintSeparator("Step 2: Model Catalog - Accelerated Models"); -var catalog = await mgr.GetCatalogAsync(); -var models = await catalog.ListModelsAsync(); -Console.WriteLine($"{INFO} Total models in catalog: {models.Count}"); - -var acceleratedVariants = new List(); -foreach (var model in models) -{ - foreach (var variant in model.Variants) - { - if (IsAcceleratedVariant(variant)) - { - acceleratedVariants.Add(variant); - var runtime = variant.Info?.Runtime; - Console.WriteLine($" - {variant.Id,-50} Device: {runtime?.DeviceType,-3} EP: {runtime?.ExecutionProvider ?? "?"}"); - } - } -} - -LogResult("Catalog - Accelerated models found", acceleratedVariants.Count > 0, - acceleratedVariants.Count > 0 ? $"{acceleratedVariants.Count} accelerated variant(s)" : "No accelerated model variants"); - -if (acceleratedVariants.Count == 0) -{ - Console.WriteLine($"\n{FAIL} No accelerated model variants are available."); - Console.WriteLine($"{WARN} Ensure the system has a compatible accelerator and matching model variants installed."); - PrintSummary(); - return; -} - -// ── 3. Download & Load Model ────────────────────────────── -PrintSeparator("Step 3: Download & Load Model"); -IModel? chosen = null; -Exception? lastLoadError = null; -var downloadedAny = false; - -foreach (var candidate in acceleratedVariants) -{ - var ep = candidate.Info?.Runtime?.ExecutionProvider ?? "unknown"; - Console.WriteLine($"\n{INFO} Trying model: {candidate.Id} (EP: {ep})"); - - try - { - await candidate.DownloadAsync(progress => - Console.Write($"\r Downloading model: {progress:F1}%")); - Console.WriteLine(); - downloadedAny = true; - } - catch (Exception e) - { - Console.WriteLine(); - Console.WriteLine($"{WARN} Skipping {candidate.Id}: download failed: {e.Message}"); - lastLoadError = e; - continue; - } - - try - { - await candidate.LoadAsync(); - chosen = candidate; - break; - } - catch (Exception e) - { - Console.WriteLine($"{WARN} Skipping {candidate.Id}: load failed: {e.Message}"); - lastLoadError = e; - } -} - -LogResult("Model Download", downloadedAny, - downloadedAny ? "At least one accelerated variant downloaded" : lastLoadError?.Message ?? "No accelerated variant could be downloaded"); - -if (chosen == null) -{ - LogResult("Model Load", false, - lastLoadError?.Message ?? "No accelerated variant could be loaded on this machine"); - PrintSummary(); - return; -} - -LogResult("Model Load", true, $"Loaded {chosen.Id}"); - -// ── 4. Streaming Chat Completions (Native SDK) ──────────── -PrintSeparator("Step 4: Streaming Chat Completions (Native)"); -try -{ - var chatClient = await chosen.GetChatClientAsync(); - chatClient.Settings.Temperature = 0; - chatClient.Settings.MaxTokens = 16; - var messages = new List - { - new() { Role = "system", Content = "You are a helpful assistant." }, - new() { Role = "user", Content = "What is 2 + 2? Reply with just the number." }, - }; - - var fullResponse = ""; - var start = DateTime.UtcNow; - await foreach (var chunk in chatClient.CompleteChatStreamingAsync(messages, ct)) - { - var content = chunk.Choices?.FirstOrDefault()?.Message?.Content; - if (!string.IsNullOrEmpty(content)) - { - Console.Write(content); - Console.Out.Flush(); - fullResponse += content; - } - } - - var elapsed = (DateTime.UtcNow - start).TotalSeconds; - Console.WriteLine(); - LogResult("Streaming Chat (Native)", fullResponse.Length > 0, - $"{fullResponse.Length} chars in {elapsed:F2}s"); -} -catch (Exception e) -{ - LogResult("Streaming Chat (Native)", false, e.Message); -} - -// ── Summary ────────────────────────────────────────────── -PrintSummary(); - -await chosen.UnloadAsync(); -Console.WriteLine("Model unloaded. Done!"); diff --git a/samples/cs/verify-winml/README.md b/samples/cs/verify-winml/README.md deleted file mode 100644 index 88540fbc8..000000000 --- a/samples/cs/verify-winml/README.md +++ /dev/null @@ -1,21 +0,0 @@ -# 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 uses registered WinML -EP-backed model variants and finishes with one native streaming chat check. - -## Prerequisites - -- Windows with a compatible GPU -- .NET 9.0 SDK - -## Build & Run - -This sample uses the `Microsoft.AI.Foundry.Local.WinML` SDK package selected by -the shared central package versions. The SDK package owns its native -`Microsoft.AI.Foundry.Local.Core.WinML` dependency, so it restores the matching -Core package transitively. - -```bash -dotnet run -``` diff --git a/samples/cs/verify-winml/VerifyWinML.csproj b/samples/cs/verify-winml/VerifyWinML.csproj deleted file mode 100644 index 860aa6740..000000000 --- a/samples/cs/verify-winml/VerifyWinML.csproj +++ /dev/null @@ -1,28 +0,0 @@ - - - - Exe - enable - enable - net9.0 - - - - $(NETCoreSdkRuntimeIdentifier) - - - - - - - - - - - - - - - - - diff --git a/samples/js/README.md b/samples/js/README.md index 0b7d677c4..2636a88c0 100644 --- a/samples/js/README.md +++ b/samples/js/README.md @@ -2,6 +2,9 @@ These samples demonstrate how to use the Foundry Local JavaScript SDK (`foundry-local-sdk`) with Node.js. +The samples consume the SDK **directly from local source** (`../../sdk/js` via a `file:` dependency), +so they always track `main` rather than a published npm version. + ## Prerequisites - [Node.js](https://nodejs.org/) (v18 or later recommended) @@ -10,20 +13,10 @@ These samples demonstrate how to use the Foundry Local JavaScript SDK (`foundry- | Sample | Description | |--------|-------------| -| [native-chat-completions](native-chat-completions/) | Initialize the SDK, download a model, and run non-streaming and streaming chat completions. | -| [embeddings](embeddings/) | Generate single and batch text embeddings using the Foundry Local SDK. | -| [audio-transcription-example](audio-transcription-example/) | Transcribe audio files using the Whisper model with streaming output. | -| [chat-and-audio-foundry-local](chat-and-audio-foundry-local/) | Unified sample demonstrating both chat and audio transcription in one application. | -| [electron-chat-application](electron-chat-application/) | Full-featured Electron desktop chat app with voice transcription and model management. | -| [copilot-sdk-foundry-local](copilot-sdk-foundry-local/) | GitHub Copilot SDK integration with Foundry Local for agentic AI workflows. | -| [langchain-integration-example](langchain-integration-example/) | LangChain.js integration for building text generation chains. | -| [tool-calling-foundry-local](tool-calling-foundry-local/) | Tool calling with custom function definitions and streaming responses. | -| [web-server-example](web-server-example/) | Start a local OpenAI-compatible web server and call it with the OpenAI SDK. | -| [web-server-responses-vision-example](web-server-responses-vision-example/) | Stream a vision (image understanding) response from the local web server using the Responses API. | -| [tutorial-chat-assistant](tutorial-chat-assistant/) | Build an interactive multi-turn chat assistant (tutorial). | -| [tutorial-document-summarizer](tutorial-document-summarizer/) | Summarize documents with AI (tutorial). | -| [tutorial-tool-calling](tutorial-tool-calling/) | Create a tool-calling assistant (tutorial). | -| [tutorial-voice-to-text](tutorial-voice-to-text/) | Transcribe and summarize audio (tutorial). | +| [chat-completion](chat-completion/) | Run the same chat prompt two ways: native in-process inference (streaming and non-streaming) **and** the local OpenAI-compatible web server (`/v1/chat/completions`). | +| [embeddings](embeddings/) | Generate single and batch text embeddings using native inference. | +| [audio](audio/) | Live microphone streaming (Nemotron ASR) **and** file-based transcription (`--file `, Whisper) in one app. | +| [responses-api](responses-api/) | Stream a vision (image understanding) response from the local web server using the Responses API. | ## Running a Sample @@ -37,7 +30,7 @@ These samples demonstrate how to use the Foundry Local JavaScript SDK (`foundry- 1. Navigate to a sample and install dependencies: ```bash - cd native-chat-completions + cd chat-completion npm install ``` @@ -48,4 +41,8 @@ These samples demonstrate how to use the Foundry Local JavaScript SDK (`foundry- ``` > [!TIP] -> Each sample's `package.json` includes `foundry-local-sdk` as a dependency and `foundry-local-sdk-winml` as an optional dependency. On **Windows**, the WinML variant installs automatically for broader hardware acceleration. On **macOS and Linux**, the standard SDK is used. Just run `npm install` — platform detection is handled for you. +> Each sample's `package.json` references the SDK via `"foundry-local-sdk": "file:../../../sdk/js"`, +> so `npm install` builds against the in-repo SDK. The SDK ships a prebuilt `dist/` and downloads its +> native runtime on install. If you've changed the SDK source, rebuild it first with +> `npm install && npm run build` (and `npm run build:native` to rebuild the native addon) inside +> `sdk/js`. diff --git a/samples/js/audio-transcription-example/app.js b/samples/js/audio-transcription-example/app.js deleted file mode 100644 index 51b69f990..000000000 --- a/samples/js/audio-transcription-example/app.js +++ /dev/null @@ -1,77 +0,0 @@ -// -// -import { FoundryLocalManager } from 'foundry-local-sdk'; -// - -// Initialize the Foundry Local SDK -console.log('Initializing Foundry Local SDK...'); - -// -const manager = FoundryLocalManager.create({ - appName: 'foundry_local_samples', - logLevel: 'info' -}); -// -console.log('✓ SDK initialized successfully'); - -// Download and register all execution providers. -let currentEp = ''; -await manager.downloadAndRegisterEps((epName, percent) => { - if (epName !== currentEp) { - if (currentEp !== '') process.stdout.write('\n'); - currentEp = epName; - } - process.stdout.write(`\r ${epName.padEnd(30)} ${percent.toFixed(1).padStart(5)}%`); -}); -if (currentEp !== '') process.stdout.write('\n'); - -// -// Get the model object -const modelAlias = 'whisper-tiny'; // Using an available model from the list above -let model = await manager.catalog.getModel(modelAlias); -console.log(`Using model: ${model.id}`); - -// Download the model -console.log(`\nDownloading model ${modelAlias}...`); -await model.download((progress) => { - process.stdout.write(`\rDownloading... ${progress.toFixed(2)}%`); -}); -console.log('\n✓ Model downloaded'); - -// Load the model -console.log(`\nLoading model ${modelAlias}...`); -await model.load(); -console.log('✓ Model loaded'); -// - -// -// Create audio client -console.log('\nCreating audio client...'); -const audioClient = model.createAudioClient(); -console.log('✓ Audio client created'); - -// Example audio transcription -const audioFile = process.argv[2] || './Recording.mp3'; -console.log(`\nTranscribing ${audioFile}...`); -const transcription = await audioClient.transcribe(audioFile); - -console.log('\nAudio transcription result:'); -console.log(transcription.text); -console.log('✓ Audio transcription completed'); - -// Same example but with streaming transcription using async iteration -console.log('\nTesting streaming audio transcription...'); -for await (const result of audioClient.transcribeStreaming(audioFile)) { - // Output the intermediate transcription results as they are received without line ending - process.stdout.write(result.text); -} -console.log('\n✓ Streaming transcription completed'); -// - -// -// Unload the model -console.log('Unloading model...'); -await model.unload(); -console.log(`✓ Model unloaded`); -// -// diff --git a/samples/js/audio-transcription-example/package.json b/samples/js/audio-transcription-example/package.json deleted file mode 100644 index 14a2aafab..000000000 --- a/samples/js/audio-transcription-example/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "audio-transcription-example", - "version": "1.0.0", - "type": "module", - "main": "app.js", - "scripts": { - "start": "node app.js" - }, - "dependencies": { - "foundry-local-sdk": "latest" - }, - "optionalDependencies": { - "foundry-local-sdk-winml": "latest" - } -} diff --git a/samples/js/audio/README.md b/samples/js/audio/README.md new file mode 100644 index 000000000..fcb440828 --- /dev/null +++ b/samples/js/audio/README.md @@ -0,0 +1,102 @@ +# Audio Transcription + +A single app with **two transcription modes** using the Foundry Local JS SDK: + +- **Live microphone streaming (default)** — real-time mic-to-text using the **Nemotron** streaming ASR model. +- **File-based transcription** — transcribe an audio file via `--file ` using the **Whisper** model. A bundled `Recording.mp3` is used when no path is supplied. + +## Prerequisites + +- [Foundry Local](https://github.com/microsoft/Foundry-Local) installed +- [Node.js](https://nodejs.org/) v18 or later +- A microphone (live mode only — falls back to synthetic audio if `naudiodon2` is unavailable) + +## Install + +This sample consumes the JS SDK **directly from local source** (`sdk/js`) so it always tracks +`main` rather than a published npm version. It is **not** pinned to a registry release. The +dependency in `package.json` is: + +```json +"foundry-local-sdk": "file:../../../sdk/js" +``` + +Install dependencies: + +```bash +npm install +``` + +> **Building the SDK:** `npm install` resolves `foundry-local-sdk` from `sdk/js`. The SDK ships a +> prebuilt `dist/` and downloads its native runtime on install. If the local SDK has not been built +> (or you've changed its source), build it first: +> +> ```bash +> cd ../../../sdk/js +> npm install +> npm run build # compile TypeScript -> dist/ +> npm run build:native # (re)build the native addon if needed +> ``` + +> **Note:** `naudiodon2` is an **optional** dependency that provides cross-platform microphone +> capture for live mode. Without it, live mode falls back to synthetic audio for testing. File +> mode does not require it. + +## Run + +```bash +# Live microphone streaming (Nemotron) — default +npm start +# or +node app.js + +# Transcribe the bundled Recording.mp3 (Whisper) +node app.js --file + +# Transcribe a specific audio file (Whisper) +node app.js --file ./my-audio.mp3 +``` + +In live mode, speak into your microphone — transcription appears in real-time. Press `Ctrl+C` to stop. + +## How it works + +### Live mode (Nemotron streaming ASR) + +1. Loads the Nemotron streaming ASR model and creates a `LiveAudioTranscriptionSession` + (16kHz / 16-bit / mono PCM). +2. Captures microphone audio via `naudiodon2` (or generates synthetic audio as a fallback). +3. Pushes PCM chunks to the SDK via `session.append()`. +4. Reads results via `for await (const result of session.getStream())`. +5. Accesses text via `result.content[0].text` (OpenAI Realtime ConversationItem pattern). + +### File mode (Whisper) + +1. Downloads and registers execution providers, then loads the `whisper-tiny` model. +2. Creates an audio client. +3. Runs non-streaming transcription via `audioClient.transcribe(file)`. +4. Runs streaming transcription via `for await (const result of audioClient.transcribeStreaming(file))`. + +## API (live mode) + +```javascript +const audioClient = model.createAudioClient(); +const session = audioClient.createLiveTranscriptionSession(); +session.settings.sampleRate = 16000; +session.settings.channels = 1; +session.settings.language = 'en'; + +await session.start(); + +// Push audio +await session.append(pcmBytes); + +// Read results +for await (const result of session.getStream()) { + console.log(result.content[0].text); // transcribed text + console.log(result.content[0].transcript); // alias (OpenAI compat) + console.log(result.is_final); // true for final results +} + +await session.stop(); +``` diff --git a/samples/js/audio-transcription-example/Recording.mp3 b/samples/js/audio/Recording.mp3 similarity index 100% rename from samples/js/audio-transcription-example/Recording.mp3 rename to samples/js/audio/Recording.mp3 diff --git a/samples/js/audio/app.js b/samples/js/audio/app.js new file mode 100644 index 000000000..6f23ac93c --- /dev/null +++ b/samples/js/audio/app.js @@ -0,0 +1,293 @@ +// Audio Transcription Example — Foundry Local JS SDK +// +// Two modes in a single app: +// • Live microphone streaming (default) using Nemotron streaming ASR. +// • File-based transcription via `--file ` using Whisper (defaults to +// the bundled Recording.mp3 when no path is given). +// +// Live capture requires: npm install naudiodon2 +// +// Usage: +// node app.js # live mic streaming (Nemotron) +// node app.js --file # transcribe bundled Recording.mp3 (Whisper) +// node app.js --file # transcribe a specific audio file (Whisper) + +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; +import { FoundryLocalManager } from 'foundry-local-sdk'; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); + +// --- Parse CLI args --- +// `--file` (optionally followed by a path) selects file-based transcription. +// Without a path it falls back to the bundled Recording.mp3. +const fileFlagIndex = process.argv.indexOf('--file'); +const fileMode = fileFlagIndex !== -1; +const fileArg = fileMode ? process.argv[fileFlagIndex + 1] : undefined; +const audioFilePath = fileMode + ? (fileArg && !fileArg.startsWith('--') ? fileArg : path.join(__dirname, 'Recording.mp3')) + : undefined; + +console.log('╔══════════════════════════════════════════════════════════╗'); +console.log('║ Foundry Local — Audio Transcription (JS SDK) ║'); +console.log('╚══════════════════════════════════════════════════════════╝'); +console.log(); + +// Initialize the Foundry Local SDK +console.log('Initializing Foundry Local SDK...'); +const manager = FoundryLocalManager.create({ + appName: 'foundry_local_samples', + logLevel: 'info' +}); +console.log('✓ SDK initialized'); + +if (fileMode) { + await runFileTranscription(manager, audioFilePath); +} else { + await runLiveTranscription(manager); +} + +// --- File-based transcription (Whisper) --- +async function runFileTranscription(manager, audioFile) { + console.log(`\nMode: file-based transcription (${audioFile})`); + + // Download and register all execution providers. + let currentEp = ''; + await manager.downloadAndRegisterEps((epName, percent) => { + if (epName !== currentEp) { + if (currentEp !== '') process.stdout.write('\n'); + currentEp = epName; + } + process.stdout.write(`\r ${epName.padEnd(30)} ${percent.toFixed(1).padStart(5)}%`); + }); + if (currentEp !== '') process.stdout.write('\n'); + + // Get the Whisper model + const modelAlias = 'whisper-tiny'; + const model = await manager.catalog.getModel(modelAlias); + console.log(`Using model: ${model.id}`); + + console.log(`\nDownloading model ${modelAlias}...`); + await model.download((progress) => { + process.stdout.write(`\rDownloading... ${progress.toFixed(2)}%`); + }); + console.log('\n✓ Model downloaded'); + + console.log(`\nLoading model ${modelAlias}...`); + await model.load(); + console.log('✓ Model loaded'); + + // Create audio client + console.log('\nCreating audio client...'); + const audioClient = model.createAudioClient(); + console.log('✓ Audio client created'); + + // Non-streaming transcription + console.log(`\nTranscribing ${audioFile}...`); + const transcription = await audioClient.transcribe(audioFile); + console.log('\nAudio transcription result:'); + console.log(transcription.text); + console.log('✓ Audio transcription completed'); + + // Streaming transcription using async iteration + console.log('\nTesting streaming audio transcription...'); + for await (const result of audioClient.transcribeStreaming(audioFile)) { + // Output intermediate transcription results as they arrive (no line ending). + process.stdout.write(result.text); + } + console.log('\n✓ Streaming transcription completed'); + + // Unload the model + console.log('\nUnloading model...'); + await model.unload(); + console.log('✓ Model unloaded'); +} + +// --- Live microphone transcription (Nemotron streaming ASR) --- +async function runLiveTranscription(manager) { + console.log('\nMode: live microphone streaming'); + + // Get and load the nemotron model + // English-only: + const modelAlias = 'nemotron-speech-streaming-en-0.6b'; + // Multi-lingual (supports 30+ languages including auto-detect): + // const modelAlias = 'nemotron-3.5-asr-streaming-0.6b'; + const model = await manager.catalog.getModel(modelAlias); + if (!model) { + console.error(`ERROR: Model "${modelAlias}" not found in catalog.`); + process.exit(1); + } + + console.log(`Found model: ${model.id}`); + console.log('Downloading model (if needed)...'); + await model.download((progress) => { + process.stdout.write(`\rDownloading... ${progress.toFixed(2)}%`); + }); + console.log('\n✓ Model downloaded'); + + console.log('Loading model...'); + await model.load(); + console.log('✓ Model loaded'); + + // Create live transcription session (same pattern as C# sample). + const audioClient = model.createAudioClient(); + const session = audioClient.createLiveTranscriptionSession(); + + session.settings.sampleRate = 16000; // Default is 16000; shown here for clarity + session.settings.channels = 1; + session.settings.bitsPerSample = 16; + session.settings.language = 'en'; // English (default) + // Multi-lingual examples: + // session.settings.language = 'de'; // German + // session.settings.language = 'zh-CN'; // Chinese (Simplified) + // session.settings.language = 'auto'; // Auto-detect language + + console.log('Starting streaming session...'); + await session.start(); + console.log('✓ Session started'); + + // Read transcription results in background + const readPromise = (async () => { + try { + for await (const result of session.getStream()) { + const text = result.content?.[0]?.text; + if (!text) continue; + + // `is_final` is a transcript-state marker only. It should not stop the app. + if (result.is_final) { + process.stdout.write(`\n [FINAL] ${text}\n`); + } else { + process.stdout.write(text); + } + } + } catch (err) { + if (err.name !== 'AbortError') { + console.error('Stream error:', err.message); + } + } + })(); + + // --- Microphone capture --- + // This example uses naudiodon2 for cross-platform audio capture. + // Install with: npm install naudiodon2 + // + // If you prefer a different audio library, just push PCM bytes + // (16-bit signed LE, mono, 16kHz) via session.append(). + + let audioInput; + try { + const { default: portAudio } = await import('naudiodon2'); + + audioInput = portAudio.AudioIO({ + inOptions: { + channelCount: session.settings.channels, + sampleFormat: session.settings.bitsPerSample === 16 + ? portAudio.SampleFormat16Bit + : portAudio.SampleFormat32Bit, + sampleRate: session.settings.sampleRate, + // Larger chunk size lowers callback frequency and reduces overflow risk. + framesPerBuffer: 3200, + // Allow deeper native queue during occasional event-loop stalls. + maxQueue: 64 + } + }); + + const appendQueue = []; + let pumping = false; + let warnedQueueDrop = false; + + const pumpAudio = async () => { + if (pumping) return; + pumping = true; + try { + while (appendQueue.length > 0) { + const pcm = appendQueue.shift(); + await session.append(pcm); + } + } catch (err) { + console.error('append error:', err.message); + } finally { + pumping = false; + // Handle race where new data arrived after loop exit. + if (appendQueue.length > 0) { + void pumpAudio(); + } + } + }; + + audioInput.on('data', (buffer) => { + // Single copy: slice the underlying ArrayBuffer to get an independent Uint8Array. + const copy = new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength).slice(); + + // Keep a bounded queue to avoid unbounded memory growth. + if (appendQueue.length >= 100) { + appendQueue.shift(); + if (!warnedQueueDrop) { + warnedQueueDrop = true; + console.warn('Audio append queue overflow; dropping oldest chunk to keep stream alive.'); + } + } + + appendQueue.push(copy); + void pumpAudio(); + }); + + console.log(); + console.log('════════════════════════════════════════════════════════════'); + console.log(' LIVE TRANSCRIPTION ACTIVE'); + console.log(' Speak into your microphone.'); + console.log(' Press Ctrl+C to stop.'); + console.log('════════════════════════════════════════════════════════════'); + console.log(); + + audioInput.start(); + } catch (err) { + console.warn('⚠ Could not initialize microphone (naudiodon2 may not be installed).'); + console.warn(' Install with: npm install naudiodon2'); + console.warn(' Or transcribe a file instead: node app.js --file'); + console.warn(' Falling back to synthetic audio test...'); + console.warn(); + + // Fallback: push 2 seconds of synthetic PCM (440Hz sine wave) + const sampleRate = session.settings.sampleRate; + const duration = 2; + const totalSamples = sampleRate * duration; + const pcmBytes = new Uint8Array(totalSamples * 2); + for (let i = 0; i < totalSamples; i++) { + const t = i / sampleRate; + const sample = Math.round(32767 * 0.5 * Math.sin(2 * Math.PI * 440 * t)); + pcmBytes[i * 2] = sample & 0xFF; + pcmBytes[i * 2 + 1] = (sample >> 8) & 0xFF; + } + + // Push in 100ms chunks + const chunkSize = (sampleRate / 10) * 2; + for (let offset = 0; offset < pcmBytes.length; offset += chunkSize) { + const len = Math.min(chunkSize, pcmBytes.length - offset); + await session.append(pcmBytes.slice(offset, offset + len)); + } + + console.log('✓ Synthetic audio pushed'); + console.log('Waiting briefly for final transcription results...'); + await new Promise((resolve) => setTimeout(resolve, 3000)); + await session.stop(); + await readPromise; + await model.unload(); + console.log('✓ Done'); + process.exit(0); + } + + // Handle graceful shutdown + process.on('SIGINT', async () => { + console.log('\n\nStopping...'); + if (audioInput) { + audioInput.quit(); + } + await session.stop(); + await readPromise; + await model.unload(); + console.log('✓ Done'); + process.exit(0); + }); +} diff --git a/samples/js/live-audio-transcription/package.json b/samples/js/audio/package.json similarity index 54% rename from samples/js/live-audio-transcription/package.json rename to samples/js/audio/package.json index d3e9d4cfe..a30ad3475 100644 --- a/samples/js/live-audio-transcription/package.json +++ b/samples/js/audio/package.json @@ -1,14 +1,14 @@ { - "name": "live-audio-transcription-example", + "name": "audio", "version": "1.0.0", "type": "module", - "description": "Live audio transcription example using the Foundry Local JS SDK", + "description": "Audio transcription example (live mic + file) using the Foundry Local JS SDK", "main": "app.js", "scripts": { "start": "node app.js" }, "dependencies": { - "foundry-local-sdk": "latest" + "foundry-local-sdk": "file:../../../sdk/js" }, "optionalDependencies": { "naudiodon2": "latest" diff --git a/samples/js/chat-and-audio-foundry-local/.npmrc b/samples/js/chat-and-audio-foundry-local/.npmrc deleted file mode 100644 index 114ea2a42..000000000 --- a/samples/js/chat-and-audio-foundry-local/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -registry=https://pkgs.dev.azure.com/aiinfra/PublicPackages/_packaging/ORT-Nightly/npm/registry/ -always-auth=true diff --git a/samples/js/chat-and-audio-foundry-local/package.json b/samples/js/chat-and-audio-foundry-local/package.json deleted file mode 100644 index 7404589ec..000000000 --- a/samples/js/chat-and-audio-foundry-local/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "chat-and-audio-foundry-local", - "version": "1.0.0", - "type": "module", - "description": "Unified chat + audio transcription sample using Foundry Local", - "scripts": { - "start": "node src/app.js" - }, - "dependencies": { - "foundry-local-sdk": "latest" - }, - "optionalDependencies": { - "foundry-local-sdk-winml": "latest" - } -} diff --git a/samples/js/chat-and-audio-foundry-local/src/app.js b/samples/js/chat-and-audio-foundry-local/src/app.js deleted file mode 100644 index 12ddabb9d..000000000 --- a/samples/js/chat-and-audio-foundry-local/src/app.js +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -import { FoundryLocalManager } from "foundry-local-sdk"; -import path from "path"; - -// Model aliases -const CHAT_MODEL = "phi-3.5-mini"; -const WHISPER_MODEL = "whisper-tiny"; - -async function main() { - console.log("Initializing Foundry Local SDK..."); - const manager = FoundryLocalManager.create({ - appName: "foundry_local_samples", - logLevel: "info", - }); - - // Download and register all execution providers. - let currentEp = ''; - await manager.downloadAndRegisterEps((epName, percent) => { - if (epName !== currentEp) { - if (currentEp !== '') process.stdout.write('\n'); - currentEp = epName; - } - process.stdout.write(`\r ${epName.padEnd(30)} ${percent.toFixed(1).padStart(5)}%`); - }); - if (currentEp !== '') process.stdout.write('\n'); - - const catalog = manager.catalog; - - // --- Load both models --- - console.log("\n--- Loading models ---"); - - const chatModel = await catalog.getModel(CHAT_MODEL); - if (!chatModel) { - throw new Error( - `Chat model "${CHAT_MODEL}" not found. Run "foundry model list" to see available models.` - ); - } - - const whisperModel = await catalog.getModel(WHISPER_MODEL); - if (!whisperModel) { - throw new Error( - `Whisper model "${WHISPER_MODEL}" not found. Run "foundry model list" to see available models.` - ); - } - - // Download models if not cached - if (!chatModel.isCached) { - console.log(`Downloading ${CHAT_MODEL}...`); - await chatModel.download((progress) => { - process.stdout.write(`\r ${CHAT_MODEL}: ${progress.toFixed(1)}%`); - }); - console.log(); - } - - if (!whisperModel.isCached) { - console.log(`Downloading ${WHISPER_MODEL}...`); - await whisperModel.download((progress) => { - process.stdout.write(`\r ${WHISPER_MODEL}: ${progress.toFixed(1)}%`); - }); - console.log(); - } - - // Load both models into memory - console.log(`Loading ${CHAT_MODEL}...`); - await chatModel.load(); - console.log(`Loading ${WHISPER_MODEL}...`); - await whisperModel.load(); - console.log("Both models loaded.\n"); - - // --- Step 1: Transcribe audio --- - console.log("=== Step 1: Audio Transcription ==="); - const audioClient = whisperModel.createAudioClient(); - audioClient.settings.language = "en"; - - // Update this path to point to your audio file - const audioFilePath = path.resolve("recording.mp3"); - const transcription = await audioClient.transcribe(audioFilePath); - console.log("You said:", transcription.text); - - // --- Step 2: Analyze with chat model --- - console.log("\n=== Step 2: AI Analysis ==="); - const chatClient = chatModel.createChatClient(); - chatClient.settings.temperature = 0.7; - chatClient.settings.maxTokens = 500; - - // Summarize the transcription - console.log("Generating summary...\n"); - for await (const chunk of chatClient.completeStreamingChat([ - { - role: "system", - content: - "You are a helpful assistant. Summarize the following transcribed audio and extract key themes and action items.", - }, - { role: "user", content: transcription.text }, - ])) { - const content = chunk.choices?.[0]?.delta?.content; - if (content) { - process.stdout.write(content); - } - } - console.log("\n"); - - // --- Clean up --- - await chatModel.unload(); - await whisperModel.unload(); - console.log("Done."); -} - -main().catch(console.error); diff --git a/samples/js/chat-completion/README.md b/samples/js/chat-completion/README.md new file mode 100644 index 000000000..deabe6db2 --- /dev/null +++ b/samples/js/chat-completion/README.md @@ -0,0 +1,58 @@ +# Native Chat Completions + +Runs the **same chat prompt two ways** against Foundry Local from a single app: + +1. **Native in-process inference** via the SDK's chat client (non-streaming *and* streaming). +2. The **local OpenAI-compatible web server** (`/v1/chat/completions`), called with the `openai` client. + +The output is split into clearly labelled sections so you can compare the two paths. + +## Prerequisites + +- [Foundry Local](https://github.com/microsoft/Foundry-Local) installed +- [Node.js](https://nodejs.org/) v18 or later + +## Install + +This sample consumes the JS SDK **directly from local source** (`sdk/js`) so it always tracks +`main` rather than a published npm version. It is **not** pinned to a registry release. The +dependency in `package.json` is: + +```json +"foundry-local-sdk": "file:../../../sdk/js" +``` + +Install dependencies: + +```bash +npm install +``` + +> **Building the SDK:** `npm install` resolves `foundry-local-sdk` from `sdk/js`. The SDK ships a +> prebuilt `dist/` and downloads its native runtime on install. If the local SDK has not been built +> (or you've changed its source), build it first: +> +> ```bash +> cd ../../../sdk/js +> npm install +> npm run build # compile TypeScript -> dist/ +> npm run build:native # (re)build the native addon if needed +> ``` + +## Run + +```bash +npm start +# or +node app.js +``` + +## What it does + +1. Initializes the SDK (with `webServiceUrls` so the local web server has a known endpoint). +2. Discovers, downloads, and registers execution providers. +3. Downloads and loads the `qwen2.5-0.5b` model. +4. **Native inference** — runs `completeChat` and `completeStreamingChat`. +5. **Web server** — starts the local web service and sends the same prompt through the + OpenAI-compatible `/v1/chat/completions` endpoint. +6. Unloads the model and stops the web service. diff --git a/samples/js/native-chat-completions/app.js b/samples/js/chat-completion/app.js similarity index 60% rename from samples/js/native-chat-completions/app.js rename to samples/js/chat-completion/app.js index 2ecc43560..eef596387 100644 --- a/samples/js/native-chat-completions/app.js +++ b/samples/js/chat-completion/app.js @@ -1,15 +1,30 @@ // // import { FoundryLocalManager } from 'foundry-local-sdk'; +import { OpenAI } from 'openai'; // +// This sample runs the SAME chat prompt two ways against Foundry Local: +// 1. Native in-process inference via the SDK's chat client. +// 2. The local OpenAI-compatible web server (/v1/chat/completions). +const endpointUrl = 'http://localhost:5764'; +const prompt = 'Why is the sky blue?'; + +function section(title) { + console.log(`\n${'═'.repeat(60)}`); + console.log(` ${title}`); + console.log('═'.repeat(60)); +} + // Initialize the Foundry Local SDK console.log('Initializing Foundry Local SDK...'); // +// `webServiceUrls` is supplied so the local web server starts on a known endpoint. const manager = FoundryLocalManager.create({ appName: 'foundry_local_samples', - logLevel: 'info' + logLevel: 'info', + webServiceUrls: endpointUrl }); // console.log('✓ SDK initialized successfully'); @@ -62,25 +77,25 @@ await model.load(); console.log('✓ Model loaded'); // -// +// +section('NATIVE IN-PROCESS INFERENCE'); + // Create chat client -console.log('\nCreating chat client...'); +console.log('Creating chat client...'); const chatClient = model.createChatClient(); console.log('✓ Chat client created'); // Example chat completion -console.log('\nTesting chat completion...'); +console.log(`\nPrompt: ${prompt}`); const completion = await chatClient.completeChat([ - { role: 'user', content: 'Why is the sky blue?' } + { role: 'user', content: prompt } ]); -console.log('\nChat completion result:'); +console.log('\nResponse:'); console.log(completion.choices[0]?.message?.content); -// -// // Example streaming completion -console.log('\nTesting streaming completion...'); +console.log('\nStreaming a second prompt...'); for await (const chunk of chatClient.completeStreamingChat( [{ role: 'user', content: 'Write a short poem about programming.' }] )) { @@ -90,13 +105,38 @@ for await (const chunk of chatClient.completeStreamingChat( } } console.log('\n'); -// +// + +// +section('LOCAL WEB SERVER (OpenAI-compatible /v1/chat/completions)'); + +// Start the web service and call it with the same prompt using the OpenAI client. +console.log('Starting web service...'); +manager.startWebService(); +console.log('✓ Web service started'); + +const openai = new OpenAI({ + baseURL: endpointUrl + '/v1', + apiKey: 'notneeded', +}); + +console.log(`\nPrompt: ${prompt}`); +const response = await openai.chat.completions.create({ + model: model.id, + messages: [ + { role: 'user', content: prompt }, + ], +}); + +console.log('\nResponse:'); +console.log(response.choices[0].message.content); +// // -// Unload the model -console.log('Unloading model...'); +// Unload the model and stop the web service +console.log('\nUnloading model and stopping web service...'); await model.unload(); -console.log(`✓ Model unloaded`); +manager.stopWebService(); +console.log('✓ Model unloaded and web service stopped'); // // - \ No newline at end of file diff --git a/samples/js/web-server-example/package.json b/samples/js/chat-completion/package.json similarity index 53% rename from samples/js/web-server-example/package.json rename to samples/js/chat-completion/package.json index 336705142..93bf08de5 100644 --- a/samples/js/web-server-example/package.json +++ b/samples/js/chat-completion/package.json @@ -1,5 +1,5 @@ { - "name": "web-server-example", + "name": "chat-completion", "version": "1.0.0", "type": "module", "main": "app.js", @@ -7,10 +7,7 @@ "start": "node app.js" }, "dependencies": { - "foundry-local-sdk": "latest", + "foundry-local-sdk": "file:../../../sdk/js", "openai": "latest" - }, - "optionalDependencies": { - "foundry-local-sdk-winml": "latest" } } diff --git a/samples/js/copilot-sdk-foundry-local/.npmrc b/samples/js/copilot-sdk-foundry-local/.npmrc deleted file mode 100644 index 114ea2a42..000000000 --- a/samples/js/copilot-sdk-foundry-local/.npmrc +++ /dev/null @@ -1,2 +0,0 @@ -registry=https://pkgs.dev.azure.com/aiinfra/PublicPackages/_packaging/ORT-Nightly/npm/registry/ -always-auth=true diff --git a/samples/js/copilot-sdk-foundry-local/package.json b/samples/js/copilot-sdk-foundry-local/package.json deleted file mode 100644 index b2457d9aa..000000000 --- a/samples/js/copilot-sdk-foundry-local/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "copilot-sdk-foundry-local-sample", - "version": "1.0.0", - "description": "Sample: Using GitHub Copilot SDK with Foundry Local for agentic workflows", - "type": "module", - "scripts": { - "start": "npx tsx src/app.ts", - "tools": "npx tsx src/tool-calling.ts" - }, - "dependencies": { - "@github/copilot-sdk": "latest", - "foundry-local-sdk": "latest", - "zod": "^3.0.0" - }, - "optionalDependencies": { - "foundry-local-sdk-winml": "latest" - }, - "devDependencies": { - "tsx": "^4.0.0", - "typescript": "^5.0.0" - } -} diff --git a/samples/js/copilot-sdk-foundry-local/src/app.ts b/samples/js/copilot-sdk-foundry-local/src/app.ts deleted file mode 100644 index 4c2013517..000000000 --- a/samples/js/copilot-sdk-foundry-local/src/app.ts +++ /dev/null @@ -1,155 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -/** - * Basic Example — Copilot SDK + Foundry Local - * - * Demonstrates: - * - Bootstrapping Foundry Local (download, load, start web service) - * - Creating a BYOK session via Copilot SDK - * - Using Copilot's built-in tools (file reading) with a local model - * - Streaming responses and multi-turn conversation - * - * The app asks the local model to read its own source code using Copilot's - * built-in `view` tool, then explain what it does — showing agentic tool - * use powered entirely by on-device inference. - * - * Run: npm start - */ - -import { CopilotClient, approveAll } from "@github/copilot-sdk"; -import { FoundryLocalManager } from "foundry-local-sdk"; - -const alias = "phi-4-mini"; -const endpointUrl = "http://localhost:6543"; - -// Timeout for each model turn (ms). Override with FOUNDRY_TIMEOUT_MS env var. -// Local models on CPU can be slow — increase this on less powerful hardware. -const TIMEOUT_MS = Number(process.env.FOUNDRY_TIMEOUT_MS) || 120_000; - -type Model = Awaited>; - -// --------------------------------------------------------------------------- -// Helper: send a message and wait for the assistant's full reply. -// --------------------------------------------------------------------------- -async function sendMessage( - session: Awaited>, - prompt: string, - timeoutMs = TIMEOUT_MS, -) { - try { - await session.sendAndWait({ prompt }, timeoutMs); - } catch (err: any) { - // Foundry Local streaming may omit finish_reason, causing a - // session.error that rejects sendAndWait. Treat as non-fatal. - console.error(`\n[sendMessage error: ${err?.message ?? err}]`); - } -} - -async function main() { - let manager: FoundryLocalManager | undefined; - let model: Model | undefined; - let client: CopilotClient | undefined; - let session: Awaited> | undefined; - - try { - // --- Initialize Foundry Local --- - console.log("Initializing Foundry Local..."); - manager = FoundryLocalManager.create({ - appName: "foundry_local_samples", - webServiceUrls: endpointUrl, - }); - - // Download and register all execution providers. - let currentEp = ''; - await manager.downloadAndRegisterEps((epName, percent) => { - if (epName !== currentEp) { - if (currentEp !== '') process.stdout.write('\n'); - currentEp = epName; - } - process.stdout.write(`\r ${epName.padEnd(30)} ${percent.toFixed(1).padStart(5)}%`); - }); - if (currentEp !== '') process.stdout.write('\n'); - - model = await manager.catalog.getModel(alias); - await model.download(); - await model.load(); - console.log(`Model: ${model.id}`); - - manager.startWebService(); - const endpoint = endpointUrl + "/v1"; - console.log(`Endpoint: ${endpoint}\n`); - - // --- Create a BYOK session with Copilot's built-in tools --- - client = new CopilotClient(); - - session = await client.createSession({ - onPermissionRequest: approveAll, - model: model.id, - provider: { - type: "openai", - baseUrl: endpoint, - apiKey: "local", - wireApi: "completions", - }, - streaming: true, - workingDirectory: process.cwd(), - systemMessage: { - content: - "You are a helpful AI assistant running locally via Foundry Local. You can use your tools to read files and answer questions about them.", - }, - }); - - // print out current directory - console.log("Current working directory:", process.cwd()); - - // Stream assistant text to stdout - session.on("assistant.message_delta", (event) => { - process.stdout.write(event.data.deltaContent); - }); - session.on("tool.execution_start", (event) => { - console.log(`\n [Tool: ${(event as any).data?.toolName ?? "unknown"}]`); - }); - - // --- Turn 1: Ask the model to read and explain its own source --- - console.log("--- Turn 1: Read and explain this app ---\n"); - process.stdout.write("Assistant: "); - await sendMessage( - session, - "Read src/app.ts, then explain what this application does in a few sentences.", - ); - console.log("\n"); - - // --- Turn 2: Follow-up leveraging conversation context --- - console.log("--- Turn 2: What technologies does it use? ---\n"); - process.stdout.write("Assistant: "); - await sendMessage(session, "What key technologies and patterns does it demonstrate?"); - console.log("\n"); - - console.log("Done!"); - } finally { - // Clean up resources in reverse order of creation - if (session) { - await session.destroy().catch(() => {}); - } - if (client) { - await client.stop().catch(() => {}); - } - if (model) { - console.log("Unloading model..."); - await model.unload().catch((e) => { - console.warn("Warning: failed to unload model:", e); - }); - } - if (manager) { - console.log("Stopping web service..."); - try { - manager.stopWebService(); - } catch (e) { - console.warn("Warning: failed to stop web service:", e); - } - } - } -} - -main().catch(console.error); diff --git a/samples/js/copilot-sdk-foundry-local/src/tool-calling.ts b/samples/js/copilot-sdk-foundry-local/src/tool-calling.ts deleted file mode 100644 index 3651b5271..000000000 --- a/samples/js/copilot-sdk-foundry-local/src/tool-calling.ts +++ /dev/null @@ -1,250 +0,0 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. - -/** - * Tool Calling Example — Copilot SDK + Foundry Local - * - * Demonstrates multiple custom tools that the model can invoke: - * - calculate: Evaluate math expressions - * - get_system_info: Return local system details - * - lookup_definition: Look up programming term definitions - * - * Run: npm run tools - */ - -import { CopilotClient, defineTool, approveAll } from "@github/copilot-sdk"; -import { FoundryLocalManager } from "foundry-local-sdk"; -import { z } from "zod"; -import * as os from "os"; - -const alias = "phi-4-mini"; -const endpointUrl = "http://localhost:6543"; - -// Timeout for each model turn (ms). Override with FOUNDRY_TIMEOUT_MS env var. -// Local models on CPU can be slow — increase this on less powerful hardware. -const TIMEOUT_MS = Number(process.env.FOUNDRY_TIMEOUT_MS) || 120_000; - -// --------------------------------------------------------------------------- -// Helper: send a message and wait for the assistant's full reply. -// Uses sendAndWait with a fallback: if the session emits an error (e.g. -// missing finish_reason from the local model), we catch it and continue. -// --------------------------------------------------------------------------- -async function sendMessage( - session: Awaited>, - prompt: string, - timeoutMs = TIMEOUT_MS, -) { - try { - await session.sendAndWait({ prompt }, timeoutMs); - } catch (err: any) { - // Foundry Local streaming may omit finish_reason, causing a - // session.error that rejects sendAndWait. Treat as non-fatal. - console.error(`\n[sendMessage error: ${err?.message ?? err}]`); - } -} - -type Model = Awaited>; - -// --------------------------------------------------------------------------- -// Tool definitions -// --------------------------------------------------------------------------- - -function defineCalculateTool() { - return defineTool("calculate", { - description: - "Evaluate a math expression and return the numeric result. " + - "Supports +, -, *, /, parentheses, and Math.* functions like Math.sqrt, Math.pow.", - parameters: z.object({ - expression: z.string().describe('Math expression to evaluate, e.g. "2 + 2" or "Math.sqrt(144)"'), - }), - handler: async (args) => { - try { - // Only allow safe math characters and Math.* calls - const sanitized = args.expression.replace(/[^0-9+\-*/().,%\s]|Math\.\w+/g, (m) => - m.startsWith("Math.") ? m : "", - ); - const result = new Function(`"use strict"; return (${sanitized})`)(); - console.log(`\n → calculate("${args.expression}") = ${result}`); - return { expression: args.expression, result: Number(result) }; - } catch { - return { expression: args.expression, error: "Could not evaluate expression" }; - } - }, - }); -} - -function defineLookupTool() { - const glossary: Record = { - "byok": "Bring Your Own Key — a pattern where you supply your own API credentials to route requests to a custom endpoint instead of the default provider.", - "onnx": "Open Neural Network Exchange — an open format for representing machine learning models, enabling interoperability between frameworks.", - "rag": "Retrieval-Augmented Generation — a technique that combines a retrieval system with a generative model so responses are grounded in external documents.", - "json-rpc": "JSON Remote Procedure Call — a lightweight protocol for calling methods on a remote server using JSON-encoded messages.", - "streaming": "A technique where the server sends response tokens incrementally as they are generated, rather than waiting for the full response.", - }; - - return defineTool("lookup_definition", { - description: - "Look up the definition of a programming or AI term. " + - "Available terms: " + Object.keys(glossary).join(", "), - parameters: z.object({ - term: z.string().describe("The term to look up (case-insensitive)"), - }), - handler: async (args) => { - const key = args.term.toLowerCase().trim(); - const definition = glossary[key]; - console.log(`\n → lookup_definition("${args.term}") → ${definition ? "found" : "not found"}`); - if (definition) { - return { term: args.term, definition }; - } - return { term: args.term, error: `Term not found. Available: ${Object.keys(glossary).join(", ")}` }; - }, - }); -} - -function defineSystemInfoTool(modelId: string, endpoint: string) { - return defineTool("get_system_info", { - description: "Get information about the local system: OS, architecture, memory, CPU count, and the running model.", - parameters: z.object({}), - handler: async () => { - const info = { - platform: os.platform(), - arch: os.arch(), - cpus: os.cpus().length, - totalMemory: `${Math.round(os.totalmem() / 1024 ** 3)} GB`, - freeMemory: `${Math.round(os.freemem() / 1024 ** 3)} GB`, - nodeVersion: process.version, - model: modelId, - endpoint, - }; - console.log(`\n → get_system_info() → ${JSON.stringify(info)}`); - return info; - }, - }); -} - -// --------------------------------------------------------------------------- -// Main -// --------------------------------------------------------------------------- - -async function main() { - let manager: FoundryLocalManager | undefined; - let model: Model | undefined; - let client: CopilotClient | undefined; - let session: Awaited> | undefined; - - try { - console.log("Initializing Foundry Local..."); - manager = FoundryLocalManager.create({ - appName: "foundry_local_samples", - webServiceUrls: endpointUrl, - }); - - // Download and register all execution providers. - let currentEp = ''; - await manager.downloadAndRegisterEps((epName, percent) => { - if (epName !== currentEp) { - if (currentEp !== '') process.stdout.write('\n'); - currentEp = epName; - } - process.stdout.write(`\r ${epName.padEnd(30)} ${percent.toFixed(1).padStart(5)}%`); - }); - if (currentEp !== '') process.stdout.write('\n'); - - model = await manager.catalog.getModel(alias); - await model.download(); - await model.load(); - console.log(`Model: ${model.id}`); - - manager.startWebService(); - const endpoint = endpointUrl + "/v1"; - console.log(`Endpoint: ${endpoint}\n`); - - const calculate = defineCalculateTool(); - const lookupDefinition = defineLookupTool(); - const getSystemInfo = defineSystemInfoTool(model.id, endpoint); - - client = new CopilotClient(); - - session = await client.createSession({ - onPermissionRequest: approveAll, - model: model.id, - provider: { - type: "openai", - baseUrl: endpoint, - apiKey: "local", - wireApi: "completions", - }, - streaming: true, - tools: [calculate, lookupDefinition, getSystemInfo], - systemMessage: { - content: - "You are a helpful AI assistant running locally via Foundry Local. " + - "You have access to tools. ALWAYS use the appropriate tool when the user asks you to " + - "calculate something, look up a term, or get system information. " + - "Do not guess — call the tool and report its result. " + - "Keep responses concise.", - }, - }); - - // Stream assistant text to stdout - session.on("assistant.message_delta", (event) => { - process.stdout.write(event.data.deltaContent); - }); - session.on("tool.execution_start", (event) => { - console.log(`\n [Tool called: ${(event as any).data?.toolName ?? "unknown"}]`); - }); - - // --- Turn 1: Calculator tool --- - console.log("=== Turn 1: Calculator ===\n"); - process.stdout.write("User: What is the square root of 144 plus 8 times 3?\n\nAssistant: "); - await sendMessage( - session, - "Use the calculate tool to compute: Math.sqrt(144) + 8 * 3", - ); - console.log("\n"); - - // --- Turn 2: Glossary lookup tool --- - console.log("=== Turn 2: Glossary Lookup ===\n"); - process.stdout.write("User: What does BYOK mean? And what about RAG?\n\nAssistant: "); - await sendMessage( - session, - "Use the lookup_definition tool to look up 'byok' and 'rag', then explain both.", - ); - console.log("\n"); - - // --- Turn 3: System info tool --- - console.log("=== Turn 3: System Info ===\n"); - process.stdout.write("User: What system am I running on?\n\nAssistant: "); - await sendMessage( - session, - "Use the get_system_info tool to check what system this is running on, then summarize.", - ); - console.log("\n"); - - console.log("Done!"); - } finally { - // Clean up resources in reverse order of creation - if (session) { - await session.destroy().catch(() => {}); - } - if (client) { - await client.stop().catch(() => {}); - } - if (model) { - console.log("Unloading model..."); - await model.unload().catch((e) => { - console.warn("Warning: failed to unload model:", e); - }); - } - if (manager) { - console.log("Stopping web service..."); - try { - manager.stopWebService(); - } catch (e) { - console.warn("Warning: failed to stop web service:", e); - } - } - } -} - -main().catch(console.error); diff --git a/samples/js/electron-chat-application/foundry_local_color.svg b/samples/js/electron-chat-application/foundry_local_color.svg deleted file mode 100644 index 412a6fb70..000000000 --- a/samples/js/electron-chat-application/foundry_local_color.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/samples/js/electron-chat-application/index.html b/samples/js/electron-chat-application/index.html deleted file mode 100644 index 5d6bd306f..000000000 --- a/samples/js/electron-chat-application/index.html +++ /dev/null @@ -1,174 +0,0 @@ - - - - - - - Foundry Local Chat - - - -
- - - - -
-
- -
-

Chat

- Select a model to start -
- -
- -
-
-
- - - -
-

Welcome to Foundry Local Chat

-

Select a model from the sidebar to start chatting with AI running locally on your machine.

-
-
- - - - 100% Private -
-
- - - - - Low Latency -
-
- - - - - - Runs Locally -
-
-
-
- -
-
-
- - - -
-
- Press Enter to send, Shift+Enter for new line - - -
-
- Context -
-
-
- 0% -
-
-
-
-
- - - - - -
- - - - diff --git a/samples/js/electron-chat-application/main.js b/samples/js/electron-chat-application/main.js deleted file mode 100644 index 92473846a..000000000 --- a/samples/js/electron-chat-application/main.js +++ /dev/null @@ -1,376 +0,0 @@ -const { app, BrowserWindow, ipcMain } = require('electron'); -const path = require('path'); -const fs = require('fs'); -const os = require('os'); - -let mainWindow; - -function createWindow() { - mainWindow = new BrowserWindow({ - width: 1200, - height: 800, - minWidth: 800, - minHeight: 600, - webPreferences: { - preload: path.join(__dirname, 'preload.js'), - contextIsolation: true, - nodeIntegration: false - }, - titleBarStyle: 'hiddenInset', - backgroundColor: '#1a1a2e' - }); - - mainWindow.loadFile('index.html'); - - // Open DevTools in development - if (process.argv.includes('--enable-logging')) { - mainWindow.webContents.openDevTools(); - } -} - -app.whenReady().then(createWindow); - -app.on('window-all-closed', () => { - if (process.platform !== 'darwin') { - app.quit(); - } -}); - -app.on('activate', () => { - if (BrowserWindow.getAllWindows().length === 0) { - createWindow(); - } -}); - -// SDK Management -let manager = null; -let currentModel = null; -let chatClient = null; -let webServiceStarted = false; -const SERVICE_PORT = 47392; -const SERVICE_URL = `http://127.0.0.1:${SERVICE_PORT}`; - -let initPromise = null; - -async function initializeSDK() { - if (initPromise) return initPromise; - - initPromise = (async () => { - const { FoundryLocalManager } = await import('foundry-local-sdk'); - manager = FoundryLocalManager.create({ - appName: 'foundry_local_samples', - logLevel: 'info', - webServiceUrls: SERVICE_URL - }); - - // Download and register all execution providers. - let currentEp = ''; - await manager.downloadAndRegisterEps((epName, percent) => { - if (epName !== currentEp) { - if (currentEp !== '') process.stdout.write('\n'); - currentEp = epName; - } - process.stdout.write(`\r ${epName.padEnd(30)} ${percent.toFixed(1).padStart(5)}%`); - }); - if (currentEp !== '') process.stdout.write('\n'); - - return manager; - })(); - - return initPromise; -} - -function ensureWebServiceStarted() { - if (!webServiceStarted && manager) { - manager.startWebService(); - webServiceStarted = true; - } -} - -// IPC Handlers -ipcMain.handle('get-models', async () => { - try { - console.log('get-models: initializing SDK...'); - await initializeSDK(); - - console.log('get-models: fetching models from catalog...'); - const models = await manager.catalog.getModels(); - console.log(`get-models: found ${models.length} models`); - - const cachedVariants = await manager.catalog.getCachedModels(); - const cachedIds = new Set(cachedVariants.map(v => v.id)); - console.log(`get-models: ${cachedVariants.length} cached models`); - - const result = models.map(m => ({ - id: m.id, - alias: m.alias, - isCached: m.isCached, - variants: m.variants.map(v => ({ - id: v.id, - alias: v.alias, - displayName: v.modelInfo.displayName || v.alias, - isCached: cachedIds.has(v.id), - fileSizeMb: v.modelInfo.fileSizeMb, - modelType: v.modelInfo.modelType, - publisher: v.modelInfo.publisher - })) - })); - - console.log('get-models: returning', result.length, 'models'); - return result; - } catch (error) { - console.error('Error getting models:', error); - throw error; - } -}); - -ipcMain.handle('download-model', async (event, modelAlias) => { - try { - await initializeSDK(); - const model = await manager.catalog.getModel(modelAlias); - if (!model) throw new Error(`Model ${modelAlias} not found`); - - await model.download(); - return { success: true }; - } catch (error) { - console.error('Error downloading model:', error); - throw error; - } -}); - -ipcMain.handle('load-model', async (event, modelAlias) => { - try { - await initializeSDK(); - - // Start web service for HTTP streaming (only once) - ensureWebServiceStarted(); - - // Unload current model if any - if (currentModel) { - try { - await currentModel.unload(); - } catch (e) { - // Ignore unload errors - } - chatClient = null; - } - - const model = await manager.catalog.getModel(modelAlias); - if (!model) throw new Error(`Model ${modelAlias} not found`); - - // Download if not cached - if (!model.isCached) { - await model.download(); - } - - await model.load(); - - // Wait for model to be fully loaded before creating chat client - while (!(await model.isLoaded())) { - await new Promise(resolve => setTimeout(resolve, 100)); - } - - currentModel = model; - chatClient = model.createChatClient(); - - return { success: true, modelId: model.id }; - } catch (error) { - console.error('Error loading model:', error); - throw error; - } -}); - -ipcMain.handle('unload-model', async () => { - try { - if (currentModel) { - await currentModel.unload(); - currentModel = null; - chatClient = null; - } - return { success: true }; - } catch (error) { - console.error('Error unloading model:', error); - throw error; - } -}); - -ipcMain.handle('delete-model', async (event, modelAlias) => { - try { - await initializeSDK(); - const model = await manager.catalog.getModel(modelAlias); - if (!model) throw new Error(`Model ${modelAlias} not found`); - - // Unload if currently loaded - if (currentModel && currentModel.alias === modelAlias) { - await currentModel.unload(); - currentModel = null; - chatClient = null; - } - - model.removeFromCache(); - return { success: true }; - } catch (error) { - console.error('Error deleting model:', error); - throw error; - } -}); - -ipcMain.handle('chat', async (event, messages) => { - if (!currentModel) throw new Error('No model loaded'); - - const startTime = performance.now(); - let firstTokenTime = null; - let tokenCount = 0; - let fullContent = ''; - - // Use HTTP streaming to avoid koffi callback issues with Electron - const response = await fetch(`${SERVICE_URL}/v1/chat/completions`, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ - model: currentModel.id, - messages, - stream: true - }) - }); - - if (!response.ok) { - throw new Error(`HTTP error: ${response.status}`); - } - - const reader = response.body.getReader(); - const decoder = new TextDecoder(); - - while (true) { - const { done, value } = await reader.read(); - if (done) break; - - const chunk = decoder.decode(value, { stream: true }); - const lines = chunk.split('\n').filter(line => line.startsWith('data: ')); - - for (const line of lines) { - const data = line.slice(6); // Remove 'data: ' prefix - if (data === '[DONE]') continue; - - try { - const parsed = JSON.parse(data); - const content = parsed.choices?.[0]?.delta?.content; - if (content) { - if (firstTokenTime === null) { - firstTokenTime = performance.now(); - } - tokenCount++; - fullContent += content; - - mainWindow.webContents.send('chat-chunk', { - content, - tokenCount, - timeToFirstToken: firstTokenTime ? (firstTokenTime - startTime) : null - }); - } - } catch (e) { - // Skip invalid JSON chunks - } - } - } - - const endTime = performance.now(); - const totalTime = endTime - startTime; - const tokensPerSecond = tokenCount > 0 ? (tokenCount / (totalTime / 1000)).toFixed(2) : 0; - - return { - content: fullContent, - stats: { - tokenCount, - timeToFirstToken: firstTokenTime ? Math.round(firstTokenTime - startTime) : 0, - totalTime: Math.round(totalTime), - tokensPerSecond: parseFloat(tokensPerSecond) - } - }; -}); - -ipcMain.handle('get-loaded-model', async () => { - if (!currentModel) return null; - return { - id: currentModel.id, - alias: currentModel.alias - }; -}); - -// Transcription handlers -ipcMain.handle('get-whisper-models', async () => { - await initializeSDK(); - const models = await manager.catalog.getModels(); - return models - .filter(m => m.alias.toLowerCase().includes('whisper')) - .map(m => ({ - alias: m.alias, - isCached: m.isCached, - fileSizeMb: m.variants[0]?.modelInfo?.fileSizeMb - })); -}); - -ipcMain.handle('download-whisper-model', async (event, modelAlias) => { - await initializeSDK(); - const model = await manager.catalog.getModel(modelAlias); - if (!model) throw new Error(`Model ${modelAlias} not found`); - await model.download(); - return { success: true }; -}); - -ipcMain.handle('transcribe-audio', async (event, audioFilePath, base64Data) => { - await initializeSDK(); - ensureWebServiceStarted(); - - // Use OS temp directory - const tempDir = os.tmpdir(); - const tempFilePath = path.join(tempDir, `foundry_audio_${Date.now()}.wav`); - - // Write audio data to temp file - const audioBuffer = Buffer.from(base64Data, 'base64'); - fs.writeFileSync(tempFilePath, audioBuffer); - - try { - // Find a cached whisper model - const models = await manager.catalog.getModels(); - const whisperModels = models.filter(m => - m.alias.toLowerCase().includes('whisper') && m.isCached - ); - - if (whisperModels.length === 0) { - throw new Error('No whisper model downloaded'); - } - - // Use the smallest cached whisper model - const selectedModel = whisperModels.sort((a, b) => { - const sizeA = a.variants[0]?.modelInfo?.fileSizeMb || 0; - const sizeB = b.variants[0]?.modelInfo?.fileSizeMb || 0; - return sizeA - sizeB; - })[0]; - - // Load whisper model - const whisperModel = await manager.catalog.getModel(selectedModel.alias); - await whisperModel.load(); - - // Wait for model to be loaded - while (!(await whisperModel.isLoaded())) { - await new Promise(resolve => setTimeout(resolve, 100)); - } - - // Create audio client and transcribe - const audioClient = whisperModel.createAudioClient(); - const result = await audioClient.transcribe(tempFilePath); - - // Unload whisper model - await whisperModel.unload(); - - return result; - } finally { - // Clean up temp file - try { - fs.unlinkSync(tempFilePath); - } catch (e) { - // Ignore cleanup errors - } - } -}); diff --git a/samples/js/electron-chat-application/package.json b/samples/js/electron-chat-application/package.json deleted file mode 100644 index 3609b2eea..000000000 --- a/samples/js/electron-chat-application/package.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "foundry-local-chat", - "version": "1.0.0", - "description": "A modern chat application using Foundry Local SDK", - "main": "main.js", - "scripts": { - "start": "electron .", - "dev": "electron . --enable-logging" - }, - "dependencies": { - "foundry-local-sdk": "latest", - "highlight.js": "^11.11.1", - "marked": "^15.0.6" - }, - "optionalDependencies": { - "foundry-local-sdk-winml": "latest" - }, - "devDependencies": { - "electron": "^42.3.3" - } -} diff --git a/samples/js/electron-chat-application/preload.js b/samples/js/electron-chat-application/preload.js deleted file mode 100644 index 7026b0b27..000000000 --- a/samples/js/electron-chat-application/preload.js +++ /dev/null @@ -1,20 +0,0 @@ -const { contextBridge, ipcRenderer } = require('electron'); - -contextBridge.exposeInMainWorld('foundryAPI', { - getModels: () => ipcRenderer.invoke('get-models'), - downloadModel: (modelAlias) => ipcRenderer.invoke('download-model', modelAlias), - loadModel: (modelAlias) => ipcRenderer.invoke('load-model', modelAlias), - unloadModel: () => ipcRenderer.invoke('unload-model'), - deleteModel: (modelAlias) => ipcRenderer.invoke('delete-model', modelAlias), - chat: (messages) => ipcRenderer.invoke('chat', messages), - getLoadedModel: () => ipcRenderer.invoke('get-loaded-model'), - onChatChunk: (callback) => { - const handler = (event, data) => callback(data); - ipcRenderer.on('chat-chunk', handler); - return () => ipcRenderer.removeListener('chat-chunk', handler); - }, - // Transcription - getWhisperModels: () => ipcRenderer.invoke('get-whisper-models'), - downloadWhisperModel: (modelAlias) => ipcRenderer.invoke('download-whisper-model', modelAlias), - transcribeAudio: (filePath, base64Data) => ipcRenderer.invoke('transcribe-audio', filePath, base64Data) -}); diff --git a/samples/js/electron-chat-application/renderer.js b/samples/js/electron-chat-application/renderer.js deleted file mode 100644 index 86b840399..000000000 --- a/samples/js/electron-chat-application/renderer.js +++ /dev/null @@ -1,1066 +0,0 @@ -// ===================================================== -// Foundry Local Chat - Renderer Process -// ===================================================== - -// Simple markdown parser with code block handling -const SimpleMarkdown = { - parse(text) { - if (!text) return ''; - - // Extract code blocks first to protect them from other processing - const codeBlocks = []; - let html = text.replace(/```(\w*)\n([\s\S]*?)```/g, (match, lang, code) => { - const placeholder = `__CODE_BLOCK_${codeBlocks.length}__`; - codeBlocks.push({ lang, code }); - return placeholder; - }); - - // Extract inline code - const inlineCodes = []; - html = html.replace(/`([^`]+)`/g, (match, code) => { - const placeholder = `__INLINE_CODE_${inlineCodes.length}__`; - inlineCodes.push(code); - return placeholder; - }); - - // Now escape HTML on the remaining text - html = this.escapeHtml(html); - - // Headings (### before ## before #) - html = html.replace(/^### (.+)$/gm, '

$1

'); - html = html.replace(/^## (.+)$/gm, '

$1

'); - html = html.replace(/^# (.+)$/gm, '

$1

'); - - // Unordered lists - html = html.replace(/^- (.+)$/gm, '
  • $1
  • '); - html = html.replace(/(
  • .*<\/li>\n?)+/g, '
      $&
    '); - - // Bold - html = html.replace(/\*\*([^*]+)\*\*/g, '$1'); - - // Italic - html = html.replace(/\*([^*]+)\*/g, '$1'); - - // Links - html = html.replace(/\[([^\]]+)\]\(([^)]+)\)/g, '
    $1'); - - // Line breaks (but not inside block elements) - html = html.replace(/\n/g, '
    '); - - // Clean up extra
    around block elements - html = html.replace(/
    ()/g, '$1'); - html = html.replace(/(<\/h[234]>)
    /g, '$1'); - html = html.replace(/
    (