Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,63 @@
{
// Agentic Inventory Planning Hack — GitHub Codespaces / VS Code Dev Containers
// Python + uv + Azure CLI + azd. post-create.sh installs dependencies and seeds src/.env.
"name": "Azure / AI / Inventory Planning Agentic",
"image": "mcr.microsoft.com/devcontainers/base:ubuntu",
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/microhack,type=bind,consistency=cached",
"workspaceFolder": "/workspaces/microhack/03-Azure/01-04-AI/03_Inventory_Planning_Agentic",
"image": "mcr.microsoft.com/devcontainers/python:3.12-bookworm",

"features": {
"ghcr.io/devcontainers/features/azure-cli:1": {
"version": "latest"
},
"ghcr.io/azure/azure-dev/azd:latest": {},
"ghcr.io/devcontainers/features/github-cli:1": {
"version": "latest"
}
},

"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.debugpy",
"ms-azuretools.azure-dev",
"ms-azuretools.vscode-azureresourcegroups",
"ms-windows-ai-studio.windows-ai-studio",
"GitHub.copilot",
"GitHub.copilot-chat"
],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash"
"terminal.integrated.defaultProfile.linux": "bash",
"python.defaultInterpreterPath": "${containerWorkspaceFolder}/src/.venv/bin/python",
"python.terminal.activateEnvironment": true
}
}
},

// Planner console (uvicorn ui.app:app --port 8000)
"forwardPorts": [8000],
"portsAttributes": {
"8000": { "label": "Planner Console", "onAutoForward": "openBrowser" }
},

// Runs once after the container is created, from workspaceFolder (the hack folder).
"postCreateCommand": "bash .devcontainer/post-create.sh",
"postAttachCommand": "bash /workspaces/${localWorkspaceFolderBasename}/.devcontainer/welcome.sh",

"remoteUser": "vscode",
"postAttachCommand": "bash /workspaces/microhack/.devcontainer/welcome.sh"
}

// Keep the Python venv on a container volume instead of the bind-mounted workspace:
// Docker Desktop (Windows/macOS) file sharing fails with I/O errors on venv-sized installs.
"mounts": [
"source=inv-agentic-venv-${devcontainerId},target=/workspaces/${localWorkspaceFolderBasename}/03-Azure/01-04-AI/03_Inventory_Planning_Agentic/src/.venv,type=volume"
],

// ${localWorkspaceFolderBasename} = the repo/fork name (e.g. microhack-labuser-0001),
// so this works for uniquely named forks in Codespaces and for local clones.
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}/03-Azure/01-04-AI/03_Inventory_Planning_Agentic",

"remoteEnv": {
"hackFolder": "/workspaces/${localWorkspaceFolderBasename}/03-Azure/01-04-AI/03_Inventory_Planning_Agentic",
"PYTHONPATH": "/workspaces/${localWorkspaceFolderBasename}/03-Azure/01-04-AI/03_Inventory_Planning_Agentic/src"
}
}
4 changes: 4 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@
"/03-Azure/01-01-App Innovation/04-adaptive-apps/**/*.yml" text eol=lf
"/03-Azure/01-01-App Innovation/04-adaptive-apps/iac/bicepconfig.json" text eol=lf
"/.devcontainer/03-azure-01-01-app-innovation-04-adaptive-apps/devcontainer.json" text eol=lf
# Agentic Inventory Planning: shell scripts run inside the dev container and must keep LF endings
"/03-Azure/01-04-AI/03_Inventory_Planning_Agentic/**/*.sh" text eol=lf
# Shared dev container scripts run inside Linux containers; Windows autocrlf checkouts must not add CRLF
"/.devcontainer/**/*.sh" text eol=lf
Original file line number Diff line number Diff line change
@@ -1,35 +1,44 @@
{
"name": "Agentic Inventory hack",
"image": "mcr.microsoft.com/devcontainers/python:3.11-bookworm",
// Used when ONLY this hack folder is opened in VS Code ("Dev Containers: Reopen in Container").
// GitHub Codespaces and full-repo clones use the repo-root config instead:
// .devcontainer/03-azure-01-04-ai-03-inventory-planning-agentic/devcontainer.json
// Keep both in sync.
"name": "Azure / AI / Inventory Planning Agentic (hack folder)",
"image": "mcr.microsoft.com/devcontainers/python:3.12-bookworm",
"features": {
"ghcr.io/devcontainers/features/azure-cli:1": {},
"ghcr.io/azure/azure-dev/azd:latest": {},
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"forwardPorts": [8000],
"portsAttributes": {
"8000": {
"label": "Planner Console",
"onAutoForward": "openPreview"
}
"8000": { "label": "Planner Console", "onAutoForward": "openBrowser" }
},
"postCreateCommand": "bash .devcontainer/post-create.sh",
"remoteUser": "vscode",
// Python venv on a container volume — Docker Desktop bind mounts fail on venv-sized installs.
"mounts": [
"source=inv-agentic-venv-${devcontainerId},target=${containerWorkspaceFolder}/src/.venv,type=volume"
],
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"ms-python.debugpy",
"ms-azuretools.azure-dev",
"ms-azuretools.vscode-azureresourcegroups",
"teamsdevapp.vscode-ai-foundry"
"ms-windows-ai-studio.windows-ai-studio",
"GitHub.copilot",
"GitHub.copilot-chat"
],
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"python.defaultInterpreterPath": "${containerWorkspaceFolder}/src/.venv/bin/python",
"python.terminal.activateEnvironment": true
}
}
},
"remoteEnv": {
"PYTHONPATH": "${containerWorkspaceFolder}/src"
}
}
}
45 changes: 39 additions & 6 deletions 03-Azure/01-04-AI/03_Inventory_Planning_Agentic/.devcontainer/post-create.sh
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,23 +1,56 @@
#!/usr/bin/env bash
# Runs once when the Codespace / devcontainer is created.
# Runs once when the Codespace / Dev Container is created (postCreateCommand).
# Safe to re-run manually: bash .devcontainer/post-create.sh
set -euo pipefail

# Always work from the hack folder, regardless of the caller's working directory.
HACK_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$HACK_DIR"

echo "==> Checking Python 3.11+"
PYTHON_BIN="$(command -v python3 || command -v python || true)"
if [ -z "$PYTHON_BIN" ]; then
echo "ERROR: Python is missing. Rebuild the container with the 'Azure / AI / Inventory Planning Agentic' dev container configuration." >&2
exit 1
fi
if ! "$PYTHON_BIN" -c 'import sys; raise SystemExit(sys.version_info < (3, 11))'; then
echo "ERROR: Python 3.11 or newer is required (found $("$PYTHON_BIN" --version 2>&1))." >&2
exit 1
fi
"$PYTHON_BIN" --version

echo "==> Installing uv (fast Python package manager)"
python -m pip install --upgrade pip uv
export PATH="$HOME/.local/bin:$PATH"
if ! command -v uv >/dev/null 2>&1; then
"$PYTHON_BIN" -m pip install --quiet --upgrade uv \
|| curl -LsSf https://astral.sh/uv/install.sh | env UV_INSTALL_DIR="$HOME/.local/bin" UV_NO_MODIFY_PATH=1 sh
fi
# Make uv available in every new terminal, wherever it was installed.
if ! grep -q 'HOME/.local/bin' "$HOME/.bashrc" 2>/dev/null; then
echo 'export PATH="$HOME/.local/bin:$PATH"' >> "$HOME/.bashrc"
fi
uv --version

echo "==> Installing dependencies from src/pyproject.toml (uv sync)"
( cd src && uv sync )
# src/.venv is a Docker volume (see devcontainer.json "mounts"); new volumes are root-owned.
if [ -d src/.venv ] && [ ! -w src/.venv ]; then
sudo chown "$(id -u):$(id -g)" src/.venv
fi
( cd src && uv sync --python "$PYTHON_BIN" --link-mode=copy )

echo "==> Seeding src/.env (edit it with your lab dashboard values)"
if [ ! -f src/.env ]; then
cp .env.example src/.env
echo " Created src/.env from .env.example"
else
echo " src/.env already exists - leaving it unchanged"
fi

echo ""
echo "============================================================"
echo " Ready. Next steps:"
echo " 1. az login"
echo " Ready. Next steps (see challenges/challenge-01.md):"
echo " 1. az login --use-device-code"
echo " 2. Edit src/.env with PROJECT_ENDPOINT + MODEL_DEPLOYMENT_NAME + COSMOS_ENDPOINT"
echo " 3. cd src && uv run uvicorn ui.app:app --reload --port 8000"
echo " 4. Open the forwarded port 8000 and follow the console."
echo "============================================================"
echo "============================================================"
13 changes: 9 additions & 4 deletions 03-Azure/01-04-AI/03_Inventory_Planning_Agentic/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,15 +131,19 @@ it has the longest support horizon (retires **2027-03-18**), and it runs on

To complete this MicroHack you'll need:

- A **GitHub account** (for Codespaces) **or** local **Python 3.11** + [uv](https://docs.astral.sh/uv/) + **Azure CLI**.
- The **lab account from your Hackbox** — it signs you in to the Azure portal and,
via single sign-on, to **GitHub** (the lab organization, used to fork the repo and
run a **Codespace**). Prefer local? **VS Code** + **Docker Desktop** + the
**Dev Containers** extension runs the same dev container.
- Access to the **Foundry project** and **Cosmos DB** your lab automation provisioned —
you'll get a `FoundryProjectEndpoint`, `ModelDeploymentName`, and `CosmosEndpoint` on
your dashboard.
- Comfort **reading and editing Python** (the reference implementation is provided).
- That's it — no data setup (the app seeds Cosmos on first run), no other software.

> [!TIP]
> **You're ready to start when** you can open the repo in a Codespace, run `az login`,
> **You're ready to start when** you can open your fork in a Codespace using the
> **Azure / AI / Inventory Planning Agentic** dev container, run `az login`,
> and paste your three dashboard values into `src/.env`.

## Challenges
Expand All @@ -164,7 +168,7 @@ Each challenge follows the same anatomy, so you always know where to look:

### Challenge list

- **Challenge 1**: **[Get Grounded & Set Up](challenges/challenge-01.md)** *(45 min)* — the scenario, the data model, your Codespace, and the planner console.
- **Challenge 1**: **[Get Grounded & Set Up](challenges/challenge-01.md)** *(60 min)* — the scenario, the data model, your Codespace, and the planner console.
- **Challenge 2**: **[Demand Sensing](challenges/challenge-02.md)** *(60 min)* — build and deploy your first hosted agent with function tools over the governed data.
- **Challenge 3**: **[Inventory Optimisation](challenges/challenge-03.md)** *(60 min)* — a reasoning agent that produces a reorder recommendation, then read its trace.
- **Challenge 4**: **[Replenishment + Human-in-the-Loop](challenges/challenge-04.md)** *(75 min)* — a real approval gate before the only side-effecting tool.
Expand All @@ -181,7 +185,8 @@ Each challenge follows the same anatomy, so you always know where to look:
## Repository layout

```
.devcontainer/ Codespaces / devcontainer (uv, azd, Azure CLI)
.devcontainer/ Dev container for this folder + post-create.sh (Codespaces uses
/.devcontainer/03-azure-01-04-ai-03-inventory-planning-agentic)
labautomation/ Platform entry point — provisions Foundry + Cosmos DB + App Insights
src/
pyproject.toml Dependencies (managed by uv — no requirements.txt)
Expand Down
Loading
Loading