diff --git a/.github/agents/claude-on-foundry.agent.md b/.github/agents/claude-on-foundry.agent.md new file mode 100644 index 0000000..057d4a3 --- /dev/null +++ b/.github/agents/claude-on-foundry.agent.md @@ -0,0 +1,71 @@ +--- +description: >- + Deploy, verify, modify, debug, and tear down a Claude model deployment on + Microsoft Foundry using the Azure-Samples/claude starter kit (Bicep or + Terraform, single command: azd up). Drives the repo's own scripts and + env-var contract over Microsoft Entra ID (no API keys). +tools: [read, edit, search, execute] +argument-hint: "What you want to do, e.g. 'deploy claude haiku to eastus2 with 50 TPM'" +--- + +# claude-on-foundry + +You set up and operate the **Azure-Samples/claude** starter kit: one or more Claude models (haiku, sonnet, opus) deployed into Microsoft Foundry with a single command (azd up), called from the Anthropic SDK and the Claude Code CLI over Microsoft Entra ID. Bicep and Terraform variants ship side by side. + +**How users invoke you:** + +``` +@claude-on-foundry deploy claude sonnet and haiku to eastus2 +@claude-on-foundry my azd up failed with 715-123420 +@claude-on-foundry free quota held by soft-deleted accounts +@claude-on-foundry tear it all down +``` + +You follow [`skills/claude-on-foundry/SKILL.md`](../../skills/claude-on-foundry/SKILL.md) **exactly**. It contains the decision tree, the env-var contract, the error catalog, the verify and teardown sequences, and the destructive-action policy. + +## What you do + +Translate plain-English requests ("deploy", "it failed", "is it working", "add a family", "clean up") into the right script + env var combinations from this repo. Never invent commands, regions, or env vars that aren't already in the skill or the README. + +## Workflow + +### 1. Understand and check prerequisites + +1. Read [`skills/claude-on-foundry/SKILL.md`](../../skills/claude-on-foundry/SKILL.md) and identify which of the five flows (PLAN, DEPLOY, DIAGNOSE, VERIFY, MODIFY, TEARDOWN) the request maps to. +2. Confirm `az` and `azd` are installed and the user is logged in. +3. Confirm subscription eligibility (EA or MCA-E) per the PLAN section. + +### 2. Configure (only what's needed) + +1. Set config via `azd env set ` from inside the chosen variant folder (`infra-bicep/` or `infra-terraform/`). +2. Required: `CLAUDE_ORGANIZATION_NAME`, `AZURE_LOCATION`. Industry must be lowercase. +3. Pick one or more of `CLAUDE_HAIKU_MODEL` / `CLAUDE_SONNET_MODEL` / `CLAUDE_OPUS_MODEL`. Empty = skip. + +### 3. Execute + +1. Run `azd up` from the chosen variant folder. +2. The `preprovision` hook runs `scripts/preflight-claude.ps1` (catalog + quota check). Never bypass it. +3. The `postprovision` hook runs `scripts/configure-claude-code.ps1` to wire Claude Code. + +### 4. Verify + +1. Run `pwsh -File scripts/verify-claude-code.ps1` (or the `.sh` POSIX variant). Exits non-zero on hard failures. +2. For a manual spot check: source `claude-code.env.ps1` / `.sh`, then `'who are you?' | claude -p`. +3. `/status` inside `claude` should report `API provider: Microsoft Foundry`. + +### 5. Diagnose on failure + +Match the exact error string to a row in the DIAGNOSE table in the skill. Run the diagnostic command listed for that row before recommending the fix. + +### 6. Report + +Summarize what was deployed or changed, the resulting endpoint, and any manual follow-ups (data-plane role grant, quota bump request, etc.). + +## Rules + +- Follow the skill instructions precisely. Don't invent `azd` env vars, regions, or CLI flags. +- **Passwordless only.** Microsoft Entra ID via `DefaultAzureCredential` / `az login`. Never write `CLAUDE_API_KEY`, subscription IDs, tenant IDs, or tokens into any tracked file. +- **Confirm before destructive actions** (`azd down`, `az cognitiveservices account purge`, `az role assignment delete`, deleting `.azure-cli/`, editing `~/.claude/settings.json`). State exactly what will be deleted and get explicit user confirmation. Never pass `--no-prompt` to skip hooks. +- **Don't mix variants** in the same `azd env`. Use a separate env per Bicep / Terraform / region combination. +- **Industry must be lowercase.** `technology`, `finance`, `healthcare`, `education`, `retail`, `manufacturing`, `government`, `media`, `other`. +- Honor the user's region. `eastus2` and `swedencentral` host all three families; `westus2` is sonnet + opus only. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 033d9fc..4cbf818 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,6 +1,6 @@ # Repository instructions for Copilot (and other AI assistants) -> **Anyone with Copilot Chat (or another AI assistant that reads `.github/copilot-instructions.md` and `AGENTS.md`) clones this repo and instantly gets a guided experience.** Ask the assistant in plain English — *"help me deploy"*, *"my deployment failed"*, *"clean up and free quota"* — and it follows the conventions below plus the deep playbook in [`.github/skills/claude-on-foundry/SKILL.md`](./skills/claude-on-foundry/SKILL.md). +> **Anyone with Copilot Chat (or another AI assistant that reads `.github/copilot-instructions.md` and `AGENTS.md`) clones this repo and instantly gets a guided experience.** Ask the assistant in plain English — *"help me deploy"*, *"my deployment failed"*, *"clean up and free quota"* — and it follows the conventions below plus the deep playbook in [`skills/claude-on-foundry/SKILL.md`](../skills/claude-on-foundry/SKILL.md). This is the **Claude on Foundry Starter Kit** ([`Azure-Samples/claude`](https://github.com/Azure-Samples/claude) · `aka.ms/claude/start`). It provisions a Microsoft Foundry account with Claude model deployments via `azd up`, and wires the Anthropic SDK + Claude Code CLI to it using Microsoft Entra ID (no API keys). @@ -35,7 +35,7 @@ Always set vars with `azd env set ` from inside the chosen variant ## How to help the user (in priority order) -1. **Load the skill.** For any non-trivial Claude-on-Foundry task, read [`.github/skills/claude-on-foundry/SKILL.md`](./skills/claude-on-foundry/SKILL.md) first — it has the full DEPLOY / DIAGNOSE / MODIFY / VERIFY / TEARDOWN playbook. +1. **Load the skill.** For any non-trivial Claude-on-Foundry task, read [`skills/claude-on-foundry/SKILL.md`](../skills/claude-on-foundry/SKILL.md) first — it has the full DEPLOY / DIAGNOSE / MODIFY / VERIFY / TEARDOWN playbook. 2. **Diagnose, don't guess.** When a deployment fails, identify the exact error fingerprint (e.g. `715-123420`, `InsufficientQuota`, `AnthropicOrganizationCreationException`, `403 Forbidden`, `401 PermissionDenied`) and follow the matching entry in the skill's DIAGNOSE table. 3. **Run the existing scripts.** Do not invent ad-hoc `az` commands when [`Get-ClaudeCatalog.ps1`](../Get-ClaudeCatalog.ps1), [`preflight-claude.ps1`](../scripts/preflight-claude.ps1), [`configure-claude-code.ps1`](../scripts/configure-claude-code.ps1), [`verify-claude-code.ps1`](../scripts/verify-claude-code.ps1), or [`src/check_claude_quota.py`](../src/check_claude_quota.py) already cover the case. 4. **Confirm before destructive actions.** Always get explicit user OK before: `az cognitiveservices account purge`, `azd down`, `az role assignment delete`, deleting `.azure-cli/`, editing `~/.claude/settings.json`. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..48f5f20 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,40 @@ +# AGENTS.md — Claude on Foundry Starter Kit + +Guidance for AI coding agents (Claude Code, OpenAI Codex, Cursor, Gemini CLI, Amp, Goose, and others) working in this repository. GitHub Copilot reads [`.github/copilot-instructions.md`](./.github/copilot-instructions.md) natively; this file is the universal pointer for everyone else. + +This repo deploys one or more **Claude** models (haiku, sonnet, opus) into a **Microsoft Foundry** account with a single command (azd up), then wires the Anthropic SDK and the Claude Code CLI to it over **Microsoft Entra ID** (no API keys). Bicep and Terraform variants ship side by side. + +Short link: + +## Start here + +For any deploy, verify, modify, debug, or teardown request, follow the full playbook in **[`skills/claude-on-foundry/SKILL.md`](skills/claude-on-foundry/SKILL.md)**. It contains the decision tree, env-var contract, region matrix, error catalog, and destructive-action policy. + +The always-on rules below are the same ones in [`.github/copilot-instructions.md`](.github/copilot-instructions.md), restated here so non-Copilot agents have them inline. + +## Non-negotiable rules + +- **Two IaC variants ship side by side. The user picks ONE.** Never edit or run both in the same `azd env`. + - Bicep: [`infra-bicep/`](./infra-bicep/) — run `cd infra-bicep && azd up` + - Terraform: [`infra-terraform/`](./infra-terraform/) — run `cd infra-terraform && azd up` +- **Single entrypoint:** `azd up` from inside the chosen variant folder. Two hooks fire automatically: + - `preprovision` runs [`scripts/preflight-claude.ps1`](./scripts/preflight-claude.ps1) (catalog + quota gate). Never bypass it. + - `postprovision` runs [`scripts/configure-claude-code.ps1`](./scripts/configure-claude-code.ps1) to wire Claude Code + the SDK to the new deployment. +- **Configure via `azd env set `** from inside the chosen variant folder. There is no `.env` file. See the env-var contract in [`.github/copilot-instructions.md`](.github/copilot-instructions.md). +- **`CLAUDE_INDUSTRY` must be lowercase**: `technology`, `finance`, `healthcare`, `education`, `retail`, `manufacturing`, `government`, `media`, `other`. Uppercase fails with `AnthropicOrganizationCreationException`. +- **Honor the user's region.** `eastus2` and `swedencentral` host all three families; `westus2` is sonnet + opus only. Don't silently change `AZURE_LOCATION`. +- **Passwordless only.** Microsoft Entra ID via `DefaultAzureCredential` / `az login`. Never write `CLAUDE_API_KEY`, subscription IDs, tenant IDs, or tokens into any tracked file. Real values live in env vars, the gitignored `.env.local`, or the gitignored `.azure-cli/` token cache. +- **Confirm before destructive actions.** Always get explicit user OK before: `azd down`, `az cognitiveservices account purge`, `az role assignment delete`, deleting `.azure-cli/`, editing `~/.claude/settings.json`. Never pass `--no-prompt` to skip hooks. +- **Diagnose, don't guess.** When a deployment fails, identify the exact error fingerprint (`715-123420`, `InsufficientQuota`, `AnthropicOrganizationCreationException`, `403 Forbidden`, `401 PermissionDenied`) and follow the matching row in the skill's DIAGNOSE table. +- **Run the existing scripts.** Don't invent ad-hoc `az` commands when [`Get-ClaudeCatalog.ps1`](./Get-ClaudeCatalog.ps1), [`scripts/preflight-claude.ps1`](./scripts/preflight-claude.ps1), [`scripts/configure-claude-code.ps1`](./scripts/configure-claude-code.ps1), [`scripts/verify-claude-code.ps1`](./scripts/verify-claude-code.ps1), or [`src/check_claude_quota.py`](./src/check_claude_quota.py) already cover the case. + +## Verify + +After a deploy, run [`scripts/verify-claude-code.ps1`](./scripts/verify-claude-code.ps1) (or `scripts/verify-claude-code.sh`). It checks the activator, env vars, `.vscode/settings.json`, `az` login + tenant, `claude` on PATH, then does a `claude -p` round trip per deployed family. Exits non-zero on hard failures. + +## Reference + +- Full README: [README.md](./README.md) +- Skill body: [`skills/claude-on-foundry/SKILL.md`](skills/claude-on-foundry/SKILL.md) +- Agent Skills manifest: [`.github/agents/claude-on-foundry.agent.md`](.github/agents/claude-on-foundry.agent.md) +- Copilot always-on rules: [`.github/copilot-instructions.md`](.github/copilot-instructions.md) diff --git a/README.md b/README.md index 5165cca..8eafe5a 100644 --- a/README.md +++ b/README.md @@ -82,11 +82,11 @@ The Python sample under [`src/`](./src/) works against either. > **Looking for something more advanced?** Jump to: [Claude Code post-deploy setup](#claude-code-post-deploy-setup) · [auto-refreshing Entra ID tokens for long-running processes](#advanced-long-running-processes-auto-refreshing-the-entra-id-token) · [preprovision preflight](#preprovision-preflight-marketplace-catalog--quota) · [check Claude quota & capacity programmatically](#advanced-check-claude-quota--capacity-programmatically). -## Need help? Ask Copilot +## Need help? Ask your AI agent -This repo ships a **GitHub Copilot skill** so any AI assistant that reads `.github/copilot-instructions.md` or `AGENTS.md` (Copilot Chat, Claude Code, Cursor, and friends) onboards you in plain English — no need to scroll the troubleshooting table or memorize env vars. +This repo ships an AI agent skill in the open [Agent Skills](https://agentskills.io/) format, so any assistant that reads [`AGENTS.md`](./AGENTS.md) or [`.github/copilot-instructions.md`](./.github/copilot-instructions.md) — GitHub Copilot Chat, Claude Code, OpenAI Codex, Cursor, Gemini CLI, Amp, Goose, Junie, Qodo, and friends — onboards you in plain English. No need to scroll the troubleshooting table or memorize env vars. -**How to use it:** clone the repo, open it in VS Code with [GitHub Copilot Chat](https://docs.github.com/copilot) (or your preferred agent), and ask in natural language. Try: +**How to use it:** clone the repo, open it in your preferred agent, and ask in natural language. Try: - *"Deploy Claude haiku to `eastus2` with 50 TPM."* - *"Why is `azd up` failing with `715-123420`?"* @@ -94,7 +94,13 @@ This repo ships a **GitHub Copilot skill** so any AI assistant that reads `.gith - *"Verify Claude Code is wired up to my Foundry deployment."* - *"Tear it all down cleanly."* -The assistant follows the playbook in [`.github/skills/claude-on-foundry/SKILL.md`](./.github/skills/claude-on-foundry/SKILL.md) and the always-on rules in [`.github/copilot-instructions.md`](./.github/copilot-instructions.md) — using this repo's scripts, env-var contract, region matrix, and error catalog instead of guessing. It also confirms with you before any destructive action (`azd down`, `az cognitiveservices account purge`, RBAC removal). +Already cloned and in a workspace? Your agent picks the skill up automatically. To add it to a different workspace, run: + +```bash +npx skills add Azure-Samples/claude +``` + +The assistant follows the playbook in [`skills/claude-on-foundry/SKILL.md`](./skills/claude-on-foundry/SKILL.md) and the always-on rules in [`AGENTS.md`](./AGENTS.md) / [`.github/copilot-instructions.md`](./.github/copilot-instructions.md) — using this repo's scripts, env-var contract, region matrix, and error catalog instead of guessing. It also confirms with you before any destructive action (`azd down`, `az cognitiveservices account purge`, RBAC removal). ## Prerequisites diff --git a/.github/skills/claude-on-foundry/SKILL.md b/skills/claude-on-foundry/SKILL.md similarity index 99% rename from .github/skills/claude-on-foundry/SKILL.md rename to skills/claude-on-foundry/SKILL.md index 49b1f54..8a66412 100644 --- a/.github/skills/claude-on-foundry/SKILL.md +++ b/skills/claude-on-foundry/SKILL.md @@ -235,7 +235,8 @@ Each `.ps1` has a `.sh` POSIX equivalent next to it. ## Reference - Long-form docs and full troubleshooting table: [README.md](../../README.md) -- Always-on instructions for AI assistants: [`.github/copilot-instructions.md`](../copilot-instructions.md) +- Always-on instructions for AI assistants: [`.github/copilot-instructions.md`](../../.github/copilot-instructions.md) +- Universal agent pointer: [`AGENTS.md`](../../AGENTS.md) - Architecture overview: [`docs/img/architecture.png`](../../docs/img/architecture.png) - Microsoft Learn — [Use Claude in Microsoft Foundry](https://learn.microsoft.com/azure/ai-foundry/foundry-models/how-to/use-foundry-models-claude) - Microsoft Learn — [Configure Claude Code for Foundry](https://learn.microsoft.com/azure/foundry/foundry-models/how-to/configure-claude-code)