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 @@ -254,12 +254,11 @@ static string BuildFoundryUrl(string projectEndpoint, string agent, string sessi
var parts = new Uri(projectEndpoint);
var project = parts.AbsolutePath.TrimEnd('/').Split('/')[^1];
var qs = HttpUtility.ParseQueryString(string.Empty);
qs["project_name"] = project;
qs["agent_name"] = agent;
qs["api-version"] = apiVersion;
qs["agent_session_id"] = sessionId;
var scheme = parts.Scheme is "https" or "wss" ? "wss" : "ws";
return $"{scheme}://{parts.Host}/api/projects/agents/endpoint/protocols/invocations_ws?{qs}";
var path = $"/api/projects/{Uri.EscapeDataString(project)}/agents/{Uri.EscapeDataString(agent)}/endpoint/protocols/invocations_ws";
return $"{scheme}://{parts.Host}{path}?{qs}";
}

static async Task<string> GetEntraTokenAsync(string resource = "https://ai.azure.com")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,10 +205,8 @@ data-plane** WebSocket URL (the proxy and `E2ELocal` build this for
you from `--foundry` + `--agent`):

```
wss://<account>.services.ai.azure.com/api/projects/agents/endpoint/protocols/invocations_ws
wss://<account>.services.ai.azure.com/api/projects/<project>/agents/<agent>/endpoint/protocols/invocations_ws
?api-version=v1
&project_name=<project>
&agent_name=<agent>
&agent_session_id=<unique-session-id>
```

Expand All @@ -217,10 +215,10 @@ Where the segments come from:
| Part | Value |
|------|-------|
| `<account>` | AI Services account host — the same host as your Foundry project endpoint (`https://<account>.services.ai.azure.com/api/projects/<project>`). |
| `/api/projects/agents/endpoint/protocols/invocations_ws` | Fixed data-plane route — `agents` and `endpoint` are literal path segments, not your agent name. The actual agent is picked via the `agent_name` query parameter. |
| `/api/projects/<project>/agents/<agent>/endpoint/protocols/invocations_ws` | Data-plane route; project and agent are URL-encoded path segments. |
| `api-version=v1` | Foundry data-plane API version. |
| `project_name=<project>` | The last segment of your project endpoint path. |
| `agent_name=<agent>` | Matches the agent `name` in [`agent.manifest.yaml`](agent.manifest.yaml) — `hello-world-dotnet-invocations-ws`. |
| `<project>` | The last segment of your project endpoint path. |
| `<agent>` | Matches the agent `name` in [`agent.manifest.yaml`](agent.manifest.yaml) — `hello-world-dotnet-invocations-ws`. |
| `agent_session_id=<unique-session-id>` | A caller-generated string that identifies the conversation. Reuse the same id to resume; use a fresh one (e.g. a GUID) to start a new session. |

Every request must also include `Authorization: Bearer <Entra token>`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,12 +207,11 @@ static string BuildFoundryUrl(string projectEndpoint, string agent, string sessi
var parts = new Uri(projectEndpoint);
var project = parts.AbsolutePath.TrimEnd('/').Split('/')[^1];
var qs = HttpUtility.ParseQueryString(string.Empty);
qs["project_name"] = project;
qs["agent_name"] = agent;
qs["api-version"] = apiVersion;
qs["agent_session_id"] = sessionId;
var scheme = parts.Scheme is "https" or "wss" ? "wss" : "ws";
return $"{scheme}://{parts.Host}/api/projects/agents/endpoint/protocols/invocations_ws?{qs}";
var path = $"/api/projects/{Uri.EscapeDataString(project)}/agents/{Uri.EscapeDataString(agent)}/endpoint/protocols/invocations_ws";
return $"{scheme}://{parts.Host}{path}?{qs}";
}

static async Task<string> GetEntraTokenAsync(string resource)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
agent.manifest.yaml
agent.yaml
.env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
**/__pycache__/
**/*.py[cod]
**/*.egg-info/
.eggs/

# Virtual environments
.venv/
venv/
env/

# IDE settings
.vscode/
.idea/

# Version control
.git/
.gitignore

# Docker files
.dockerignore

# Docs
README.md

# Local environment (never bake credentials into the image)
.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# ===== E2E-TESTS INFRASTRUCTURE (Existing Foundry Project) =====
# This configuration uses the pre-provisioned agents-e2e-tests-canadacentral resource group

# Full resource ID of the existing AI Foundry project
AZURE_AI_PROJECT_ID=/subscriptions/921496dc-987f-410f-bd57-426eb2611356/resourceGroups/agents-e2e-tests-canadacentral/providers/Microsoft.CognitiveServices/accounts/e2e-tests-canadacentral-account/projects/e2e-tests-canadacentral

# AI Foundry API endpoint
AZURE_AI_PROJECT_ENDPOINT=https://e2e-tests-canadacentral-account.services.ai.azure.com/api/projects/e2e-tests-canadacentral

# Subscription and region
AZURE_SUBSCRIPTION_ID=921496dc-987f-410f-bd57-426eb2611356
AZURE_ENV_NAME=e2e-tests-canadacentral
AZURE_LOCATION=canadacentral

# Existing container registry for pushing container images
AZURE_CONTAINER_REGISTRY_ENDPOINT=crco5phi2qd67pq.azurecr.io

# Optional: Application Insights
# APPLICATIONINSIGHTS_CONNECTION_STRING=...
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# ===== REQUIRED — Existing Foundry Project (Bring Your Own) =====

# Full resource ID of your existing AI Foundry project.
# Format: /subscriptions/<sub-id>/resourceGroups/<rg>/providers/Microsoft.CognitiveServices/accounts/<account>/projects/<project>
AZURE_AI_PROJECT_ID=

# AI Foundry API endpoint for your project.
# Format: https://<account>.<region>.api.ai.azure.com/api/projects/<project>
# OR: https://<account>.services.ai.azure.com/api/projects/<project>
AZURE_AI_PROJECT_ENDPOINT=

# Your Azure subscription ID.
AZURE_SUBSCRIPTION_ID=

# ===== OPTIONAL — Container Image Registry (for docker deployments) =====

# Your existing container registry endpoint (for pushing container images).
# Format: <registry>.azurecr.io
# Only needed if deploying with `language: docker` in azure.yaml
# For code-only (bundled ZIP) deployments, this is not required.
AZURE_CONTAINER_REGISTRY_ENDPOINT=

# ===== OPTIONAL — Environment Configuration =====

# Environment name (used for naming and tagging). Defaults to 'e2e-tests-canadacentral' if not set.
AZURE_ENV_NAME=e2e-tests-canadacentral

# Azure region for your deployment (informational only; resources must already exist).
AZURE_LOCATION=canadacentral

# ===== OPTIONAL — Application Insights Telemetry =====

# Application Insights connection string (auto-injected into container if set).
# APPLICATIONINSIGHTS_CONNECTION_STRING=InstrumentationKey=...

# ===== ABOUT THIS SAMPLE =====

# This diagnostic agent uses the Invocations protocol (v1.0.0).
# It does NOT call an LLM and does NOT require a model deployment.
# It only performs network/environment diagnostics inside the runtime sandbox.

# For "Bring Your Own" (BYO) infrastructure, all Azure resources must exist before deployment:
# - Foundry Account and Project (created separately)
# - Container Registry (if using docker mode) — already created
# - Resource Group with proper networking/permissions configured
#
# This sample does not provision infrastructure (no infra/ directory).
# Use: azd deploy --no-prompt (to deploy agent to existing project)
# Do NOT use: azd up (since there is no infrastructure to provision)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.azure
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
FROM python:3.12-slim
WORKDIR /app
COPY . user_agent/
WORKDIR /app/user_agent
RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
EXPOSE 8088
CMD ["python", "main.py"]
Loading
Loading