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
Expand Up @@ -98,14 +98,16 @@ Select the assigned organization, then open the pinned microhack repository.

<img src="./images/challenge-01-select-github-organization.png" alt="GitHub organization" width="60%">

<img src="./images/challenge-01-pinned-github-repository.png" alt="Microhack repository" width="60%">
<img src="./images/challenge-01-github-pinned-repository.png" alt="Microhack repository" width="60%">

You then need to fork the repository before you can create a Codespace. To fork the repository, click the Fork button in the top-right corner of the repository page and follow the prompts:

<img src="./images/challenge-01-github-fork-repository.png" alt="Create fork" width="60%">
<img src="./images/challenge-01-github-fork-repo.png" alt="Create fork" width="60%">


Select the organization as owner and use a unique name for the repository name to avoid conflicts with other forks. For example, you can append your lab username to the repository name (e.g., `microhack-labuser-0001`):


<img src="./images/challenge-01-github-fork-name.png" alt="Fork name" width="60%">

Finally, you should see your forked repository with the unique name you provided and all files and folders from the original repository:
Expand All @@ -118,13 +120,13 @@ From the repository page, select **Code**, then open the **Codespaces** tab. Sel

<img src="./images/challenge-01-new-codespace-with-options.png" alt="New Codespace" width="60%">

For Dev container configuration, select **Azure / AI / Predictive Maintenance**, then select **Create codespace**:
For **Dev container configuration**, select **Azure / AI / Predictive Maintenance**, then select **Create codespace**:

<img src="./images/challenge-01-select-devcontainer.png" alt="Select Dev Container" width="60%">

Wait for the container setup to finish, then select the **Trust folders & Continue** button and confirm that the repository files are visible in the Explorer and that the integrated terminal opens without errors.

<img src="./images/challenge-01-codespace-welccome.png" alt="Codespace welcome" width="60%">
<img src="./images/challenge-01-codespace-welcome.png" alt="Codespace welcome" width="60%">

Open a terminal in the Codespace and verify that the required tools are installed:

Expand All @@ -144,6 +146,8 @@ Sign in to Azure from the Codespace terminal follow the link shown to authentica
az login --use-device-code
```

In the **Select a subscription and tenant** terminal prompt hit enter to use the default Azure subscription

### 4. Retrieve environment configuration

From the repository root, run the setup script with the resource group name provided in your Hackbox under **Resource Group Name**:
Expand Down Expand Up @@ -186,6 +190,17 @@ az storage blob list \

The expected result is `5` wiki articles, one per machine type.

### 6. Validate the Machine API

Confirm that the provisioned Machine API in API Management can retrieve the seeded machine data:

```bash
# Get all machines
curl -fsSL "$APIM_GATEWAY_URL/machine" -H "Ocp-Apim-Subscription-Key: $APIM_SUBSCRIPTION_KEY" -H "Accept: application/json"
```

You should receive a JSON response containing the factory machines. You will use this API when building the agents in Challenge 2.

## 🚀 Go Further

Review the [solution architecture](../README.md#architecture) and identify which Azure resource each of the five agents will use in the upcoming challenges.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

**[Home](../README.md)** | [Previous challenge](challenge-01.md) | [Next challenge](challenge-03.md)

> [!TIP]
> Stuck on a step? See the [Challenge 2 walkthrough](../walkthrough/challenge-02/solution-02.md) for exact commands, expected output, and a validation checklist.

## 🎯 Objective

The goals for this challenge are:
Expand Down Expand Up @@ -145,9 +142,6 @@ Machine and threshold information is typically stored in a central system and ex
The Machine API and Maintenance API are already available in API Management and contain endpoints for getting details about a specific machine and thresholds for certain machine types. Try the APIs:

```bash
# Get all machines
curl -fsSL "$APIM_GATEWAY_URL/machine" -H "Ocp-Apim-Subscription-Key: $APIM_SUBSCRIPTION_KEY" -H "Accept: application/json"

# Get a specific machine
curl -fsSL "$APIM_GATEWAY_URL/machine/machine-001" -H "Ocp-Apim-Subscription-Key: $APIM_SUBSCRIPTION_KEY" -H "Accept: application/json"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

**[Home](../README.md)** | [Previous challenge](challenge-02.md) | [Next challenge](challenge-04.md)

> [!TIP]
> Stuck on a step? See the [Challenge 3 walkthrough](../walkthrough/challenge-03/solution-03.md) for exact commands, expected output, and a validation checklist.

## 🎯 Objective

The goals for this challenge are:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

**[Home](../README.md)** | [Previous challenge](challenge-03.md) | [Next challenge](challenge-05.md)

> [!TIP]
> Stuck on a step? See the [Challenge 4 walkthrough](../walkthrough/challenge-04/solution-04.md) for exact commands, expected output, and a validation checklist.

## 🎯 Objective

The goals for this challenge are:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@

**[Home](../README.md)** | [Previous challenge](challenge-04.md) | [Next: Wrap-up](finish.md)

> [!TIP]
> Stuck on a step? See the [Challenge 5 walkthrough](../walkthrough/challenge-05/solution-05.md) for exact commands, expected output, and a validation checklist.

## 🎯 Objective

The goals for this challenge are:
Expand Down Expand Up @@ -104,6 +101,10 @@ This challenge uses the **Sequential** pattern — see [Conclusion and Reflectio

### Task 1: Start Aspire

The Python app uses its own virtual environment with Python 3.13, pinned by
`src/agent-workflow/app/.python-version`. This is separate from the workshop's
Python 3.11 environment; `uv` selects the pinned interpreter automatically.

```bash
cd src/agent-workflow
aspire run
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ labautomation/
`-- get-keys.sh # Participant-run script: resolves resource names/keys into a repo-root .env
```

The generated `.env` uses `AZURE_AI_PROJECT_ENDPOINT` for the Foundry project endpoint
across the agents and workflow.

## What `main.bicep` provisions

- Storage account with a `machine-wiki` blob container (knowledge base articles).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.13
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ def extract_work_order_id(text: str) -> str | None:
logger.info(f"COSMOS_ENDPOINT set: {bool(os.getenv('COSMOS_ENDPOINT'))}")
logger.info(f"COSMOS_DATABASE set: {bool(os.getenv('COSMOS_DATABASE'))}")
logger.info(
f"AI_FOUNDRY_PROJECT_ENDPOINT set: {bool(os.getenv('AI_FOUNDRY_PROJECT_ENDPOINT'))}")
f"AZURE_AI_PROJECT_ENDPOINT set: {bool(os.getenv('AZURE_AI_PROJECT_ENDPOINT'))}")


# =============================================================================
Expand Down Expand Up @@ -141,8 +141,7 @@ async def execute(self, context: RequestContext, event_queue: EventQueue) -> Non
cosmos_key = os.getenv("COSMOS_KEY")
database_name = os.getenv(
"COSMOS_DATABASE_NAME") or os.getenv("COSMOS_DATABASE")
project_endpoint = os.getenv("AI_FOUNDRY_PROJECT_ENDPOINT") or os.getenv(
"AZURE_AI_PROJECT_ENDPOINT")
project_endpoint = os.getenv("AZURE_AI_PROJECT_ENDPOINT")
deployment_name = os.getenv("MODEL_DEPLOYMENT_NAME", "gpt-5.4")

if not all([cosmos_endpoint, cosmos_key, database_name, project_endpoint]):
Expand Down Expand Up @@ -305,8 +304,7 @@ async def execute(self, context: RequestContext, event_queue: EventQueue) -> Non
cosmos_key = os.getenv("COSMOS_KEY")
database_name = os.getenv(
"COSMOS_DATABASE_NAME") or os.getenv("COSMOS_DATABASE")
project_endpoint = os.getenv("AI_FOUNDRY_PROJECT_ENDPOINT") or os.getenv(
"AZURE_AI_PROJECT_ENDPOINT")
project_endpoint = os.getenv("AZURE_AI_PROJECT_ENDPOINT")
deployment_name = os.getenv("MODEL_DEPLOYMENT_NAME", "gpt-5.4")

if not all([cosmos_endpoint, cosmos_key, database_name, project_endpoint]):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,19 +300,19 @@ async def main():

print("=== Predictive Maintenance Agent ===\n")

# Load configuration (use AI_FOUNDRY_PROJECT_ENDPOINT for consistency with other challenge scripts)
# Load configuration
cosmos_endpoint = os.getenv("COSMOS_ENDPOINT")
cosmos_key = os.getenv("COSMOS_KEY")
database_name = os.getenv("COSMOS_DATABASE_NAME")
foundry_project_endpoint = os.getenv("AI_FOUNDRY_PROJECT_ENDPOINT")
foundry_project_endpoint = os.getenv("AZURE_AI_PROJECT_ENDPOINT")
deployment_name = os.getenv("MODEL_DEPLOYMENT_NAME", "gpt-5.4")
otel_exporter_endpoint = os.getenv(
"OTEL_EXPORTER_OTLP_ENDPOINT")

# Validate
if not all([cosmos_endpoint, cosmos_key, database_name, foundry_project_endpoint]):
print("Error: Missing required environment variables.")
print("Required: COSMOS_ENDPOINT, COSMOS_KEY, COSMOS_DATABASE_NAME, AI_FOUNDRY_PROJECT_ENDPOINT")
print("Required: COSMOS_ENDPOINT, COSMOS_KEY, COSMOS_DATABASE_NAME, AZURE_AI_PROJECT_ENDPOINT")
return

if otel_exporter_endpoint:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,14 +283,14 @@ async def main():
cosmos_endpoint = os.getenv("COSMOS_ENDPOINT")
cosmos_key = os.getenv("COSMOS_KEY")
database_name = os.getenv("COSMOS_DATABASE_NAME")
foundry_project_endpoint = os.getenv("AI_FOUNDRY_PROJECT_ENDPOINT")
foundry_project_endpoint = os.getenv("AZURE_AI_PROJECT_ENDPOINT")
deployment_name = os.getenv("MODEL_DEPLOYMENT_NAME", "gpt-5.4")
otel_exporter_endpoint = os.getenv(
"OTEL_EXPORTER_OTLP_ENDPOINT")

if not all([cosmos_endpoint, cosmos_key, database_name, foundry_project_endpoint]):
print("Error: Missing required environment variables.")
print("Required: COSMOS_ENDPOINT, COSMOS_KEY, COSMOS_DATABASE_NAME, AI_FOUNDRY_PROJECT_ENDPOINT")
print("Required: COSMOS_ENDPOINT, COSMOS_KEY, COSMOS_DATABASE_NAME, AZURE_AI_PROJECT_ENDPOINT")
return

if otel_exporter_endpoint:
Expand Down
Loading