This file provides context for AI coding agents (GitHub Copilot, Copilot Workspace, Codex, etc.) working in this repository.
This is a hands-on workshop for building AI applications with Foundry Local — a lightweight runtime that downloads, manages, and serves language models entirely on-device via an OpenAI-compatible API. The workshop includes step-by-step lab guides and runnable code samples in Python, JavaScript, and C#.
├── labs/ # Markdown lab guides (Parts 1–13)
├── python/ # Python code samples (Parts 2–6, 8–9, 11)
├── javascript/ # JavaScript/Node.js code samples (Parts 2–6, 8–9, 11)
├── csharp/ # C# / .NET 9 code samples (Parts 2–6, 8–9, 11)
├── zava-creative-writer-local/ # Part 7 capstone app + Part 12 UI (Python/JS/C#)
│ ├── ui/ # Shared browser UI (vanilla HTML/CSS/JS)
│ └── src/
│ ├── api/ # Python FastAPI multi-agent service (serves UI)
│ ├── javascript/ # Node.js CLI + HTTP server (server.mjs)
│ ├── csharp/ # .NET console multi-agent app
│ └── csharp-web/ # .NET ASP.NET Core minimal API (serves UI)
├── samples/audio/ # Part 9 sample WAV files + generator script
├── images/ # Diagrams referenced by lab guides
├── README.md # Workshop overview and navigation
├── KNOWN-ISSUES.md # Known issues and workarounds
├── package.json # Root devDependency (mermaid-cli for diagrams)
└── AGENTS.md # This file
- Location:
python/,zava-creative-writer-local/src/api/ - Dependencies:
python/requirements.txt,zava-creative-writer-local/src/api/requirements.txt - Key packages:
foundry-local-sdk,openai,agent-framework-foundry-local,fastapi,uvicorn - Min version: Python 3.9+
- Run:
cd python && pip install -r requirements.txt && python foundry-local.py
- Location:
javascript/,zava-creative-writer-local/src/javascript/ - Dependencies:
javascript/package.json,zava-creative-writer-local/src/javascript/package.json - Key packages:
foundry-local-sdk,openai - Module system: ES modules (
.mjsfiles,"type": "module") - Min version: Node.js 18+
- Run:
cd javascript && npm install && node foundry-local.mjs
- Location:
csharp/,zava-creative-writer-local/src/csharp/ - Project files:
csharp/csharp.csproj,zava-creative-writer-local/src/csharp/ZavaCreativeWriter.csproj - Key packages:
Microsoft.AI.Foundry.Local(non-Windows),Microsoft.AI.Foundry.Local.WinML(Windows — superset with QNN EP),OpenAI,Microsoft.Agents.AI.OpenAI - Target: .NET 9.0 (conditional TFM:
net9.0-windows10.0.26100on Windows,net9.0elsewhere) - Run:
cd csharp && dotnet run [chat|rag|agent|multi]
- All code samples are self-contained single-file examples — no shared utility libraries or abstractions.
- Each sample runs independently after installing its own dependencies.
- API keys are always set to
"foundry-local"— Foundry Local uses this as a placeholder. - Base URLs use
http://localhost:<port>/v1— the port is dynamic and discovered at runtime via the SDK (manager.urls[0]in JS,manager.endpointin Python). - The Foundry Local SDK handles service startup and endpoint discovery; prefer SDK patterns over hard-coded ports.
- Use
openaiSDK withOpenAI(base_url=..., api_key="not-required"). - Use
FoundryLocalManager()fromfoundry_localfor SDK-managed service lifecycle. - Streaming: iterate over
streamobject withfor chunk in stream:. - No type annotations in sample files (keep samples concise for workshop learners).
- ES module syntax:
import ... from "...". - Use
OpenAIfrom"openai"andFoundryLocalManagerfrom"foundry-local-sdk". - SDK init pattern:
FoundryLocalManager.create({ appName })→FoundryLocalManager.instance→manager.startWebService()→await catalog.getModel(alias). - Streaming:
for await (const chunk of stream). - Top-level
awaitis used throughout.
- Nullable enabled, implicit usings, .NET 9.
- Use
FoundryLocalManager.StartServiceAsync()for SDK-managed lifecycle. - Streaming:
CompleteChatStreaming()withforeach (var update in completionUpdates). - The main
csharp/Program.csis a CLI router dispatching to staticRunAsync()methods.
- Only certain models support tool calling: Qwen 2.5 family (
qwen2.5-*) and Phi-4-mini (phi-4-mini). - Tool schemas follow the OpenAI function-calling JSON format (
type: "function",function.name,function.description,function.parameters). - The conversation uses a multi-turn pattern: user → assistant (tool_calls) → tool (results) → assistant (final answer).
- The
tool_call_idin tool result messages must match theidfrom the model's tool call. - Python uses the OpenAI SDK directly; JavaScript uses the SDK's native
ChatClient(model.createChatClient()); C# uses the OpenAI SDK withChatTool.CreateFunctionTool().
- JavaScript:
model.createChatClient()returns aChatClientwithcompleteChat(messages, tools?)andcompleteStreamingChat(messages, callback). - C#:
model.GetChatClientAsync()returns a standardChatClientthat can be used without importing the OpenAI NuGet package. - Python does not have a native ChatClient — use the OpenAI SDK with
manager.endpointandmanager.api_key. - Important: JavaScript
completeStreamingChatuses a callback pattern, not async iteration.
phi-4-mini-reasoningwraps its thinking in<think>...</think>tags before the final answer.- Parse the tags to separate reasoning from the answer when needed.
Lab files are in labs/ as Markdown. They follow a consistent structure:
- Logo header image
- Title and goal callout
- Overview, Learning Objectives, Prerequisites
- Concept explanation sections with diagrams
- Numbered exercises with code blocks and expected output
- Summary table, Key Takeaways, Further Reading
- Navigation link to the next part
When editing lab content:
- Maintain the existing Markdown formatting style and section hierarchy.
- Code blocks must specify the language (
python,javascript,csharp,bash,powershell). - Provide both bash and PowerShell variants for shell commands where OS matters.
- Use
> **Note:**,> **Tip:**, and> **Troubleshooting:**callout styles. - Tables use the
| Header | Header |pipe format.
| Action | Command |
|---|---|
| Python samples | cd python && pip install -r requirements.txt && python <script>.py |
| JS samples | cd javascript && npm install && node <script>.mjs |
| C# samples | cd csharp && dotnet run [chat|rag|agent|multi|eval|whisper|toolcall] |
| Zava Python | cd zava-creative-writer-local/src/api && pip install -r requirements.txt && uvicorn main:app |
| Zava JS | cd zava-creative-writer-local/src/javascript && npm install && node main.mjs |
| Zava JS (web) | cd zava-creative-writer-local/src/javascript && npm install && node server.mjs |
| Zava C# | cd zava-creative-writer-local/src/csharp && dotnet run |
| Zava C# (web) | cd zava-creative-writer-local/src/csharp-web && dotnet run |
| Foundry Local CLI | foundry model list, foundry model run <model>, foundry service status |
| Generate diagrams | npx mmdc -i <input>.mmd -o <output>.svg (requires root npm install) |
- Foundry Local CLI must be installed on the developer's machine (
winget install Microsoft.FoundryLocalorbrew install foundrylocal). - Foundry Local service runs locally and exposes an OpenAI-compatible REST API on a dynamic port.
- No cloud services, API keys, or Azure subscriptions are required to run any sample.
- Part 10 (custom models) additionally requires
onnxruntime-genaiand downloads model weights from Hugging Face.
The .gitignore should exclude (and does for most):
.venv/— Python virtual environmentsnode_modules/— npm dependenciesmodels/— compiled ONNX model output (large binary files, generated by Part 10)cache_dir/— Hugging Face model download cache.olive-cache/— Microsoft Olive working directorysamples/audio/*.wav— generated audio samples (regenerated viapython samples/audio/generate_samples.py)- Standard Python build artifacts (
__pycache__/,*.egg-info/,dist/, etc.)
MIT — see LICENSE.