Skip to content

nodejs/autonomous/github-trending: support Foundry endpoints + accept canonical CLI env-var names#323

Open
Yogeshp-MSFT wants to merge 2 commits into
microsoft:mainfrom
Yogeshp-MSFT:nodejs/foundry-and-observability-support
Open

nodejs/autonomous/github-trending: support Foundry endpoints + accept canonical CLI env-var names#323
Yogeshp-MSFT wants to merge 2 commits into
microsoft:mainfrom
Yogeshp-MSFT:nodejs/foundry-and-observability-support

Conversation

@Yogeshp-MSFT

Copy link
Copy Markdown

What was changed

src/github-trending-service.ts

  • Auto-detect Azure OpenAI vs Foundry endpoints:
    • *.services.ai.azure.com / *.cognitiveservices.azure.com → plain OpenAI client with baseURL=<host>/openai/v1 and api-key default header.
    • *.openai.azure.com → existing AzureOpenAI client with apiVersion query string.
  • Strip any path the user pasted from the Foundry portal so callers can paste any of /, /api/projects/<name>, /openai/v1, /openai/v1/responses and still get a working endpoint.
  • Add apiVersion to TrendingServiceConfig (was hard-coded to 2024-12-01-preview).

src/index.ts

  • Accept canonical agent365Observability__* env-var names with fallback to legacy AGENT365_* aliases.
  • Add ENABLE_A365_OBSERVABILITY and ENABLE_A365_OBSERVABILITY_EXPORTER as opt-in flags for parity with the Python sample.
  • Pass AZURE_OPENAI_API_VERSION through to the trending service.

.env.template and README.md

  • Document Foundry endpoint support.
  • Use canonical agent365Observability__* placeholder keys.
  • List both canonical and legacy env-var names side-by-side.
  • Document the observability flags.

Why

  1. Foundry endpoints rejected the upstream client with 400 BadRequest — api-version query parameter is not allowed when using /v1 path, blocking the sample for users on a Foundry / AI Services account.
  2. The current Agent 365 CLI stamps .env with agent365Observability__* keys, but the upstream code only read AGENT365_* — leading to silent fallback to placeholder values.
  3. The Python sample exposes both observability flags; bringing them to Node provides cross-language parity.
  4. AZURE_OPENAI_API_VERSION is now configurable so users can pin to whichever GA/preview version their classic Azure OpenAI resource supports.

Validation

End-to-end runs against a Foundry account with a fresh Agent 365 identity (a365 setup all --agent-name Github-trending-nodejs):

Check Result
npm run dev startup Observability configured (a365_exporter=true, credentials_present=true)
Foundry-aware client selection ✅ Pasted Foundry URL normalized to /openai/v1/chat/completions
chat.completions against Foundry endpoint ✅ HTTP 200 OK
Tool-call loop ✅ GitHub Search returned 10 trending repos; LLM produced markdown digest
3-hop FMI token chain ✅ Token registered
A365 span tree invoke_agentChatexecute_tool with matching traceId
A365 backend export [EVENT]: agent365-export succeeded — All spans exported successfully
Legacy AGENT365_* env names ✅ Still accepted via fallback
HTTP /api/health, /, /nonexistent ✅ 200 / 200 / 404
Heartbeat (60 s) and SIGINT graceful shutdown ✅ Both working

Copilot AI review requested due to automatic review settings June 17, 2026 07:45
@Yogeshp-MSFT Yogeshp-MSFT requested a review from a team as a code owner June 17, 2026 07:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for both classic Azure OpenAI and Foundry/AI Services endpoints, while making Agent 365 observability configurable via feature flags and updated environment variable conventions.

Changes:

  • Add configurable AZURE_OPENAI_API_VERSION and pass it into the trending service.
  • Support Foundry /openai/v1 endpoints by normalizing the endpoint and switching client construction based on host.
  • Add observability feature flags and accept canonical agent365Observability__* env vars with legacy fallbacks.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 4 comments.

File Description
nodejs/autonomous/github-trending/src/index.ts Adds API version plumb-through and observability flags/env-var fallbacks.
nodejs/autonomous/github-trending/src/github-trending-service.ts Creates OpenAI client differently for Foundry vs classic Azure OpenAI; normalizes endpoint.
nodejs/autonomous/github-trending/README.md Documents new env vars, flags, and Foundry endpoint support.
nodejs/autonomous/github-trending/.env.template Updates template with canonical A365 env var names, flags, and Azure OpenAI API version.

Comment thread nodejs/autonomous/github-trending/src/github-trending-service.ts Outdated
Comment thread nodejs/autonomous/github-trending/src/github-trending-service.ts Outdated
Comment thread nodejs/autonomous/github-trending/src/github-trending-service.ts Outdated
Comment thread nodejs/autonomous/github-trending/.env.template Outdated
… canonical CLI env-var names

Adds three improvements to the Node.js github-trending sample:

1. Foundry / AI Services endpoint support
   - Detect *.services.ai.azure.com / *.cognitiveservices.azure.com hosts and
     use a plain OpenAI client at <host>/openai/v1 with an api-key default
     header (the /openai/v1 path rejects the api-version query parameter that
     AzureOpenAI would otherwise append).
   - Strip any path the user pasted from the Foundry portal (e.g.
     /api/projects/<name>, /openai/v1, /openai/v1/responses) so the endpoint
     normalizes to scheme + host before client construction.
   - Classic *.openai.azure.com endpoints continue to use AzureOpenAI with
     apiVersion (existing behavior).
   - Make AZURE_OPENAI_API_VERSION configurable via env (default 2024-10-21);
     was previously hard-coded to 2024-12-01-preview.

2. Accept canonical agent365Observability__* env-var names
   - The Agent 365 CLI (a365 setup all) auto-stamps these into .env.
   - Read them first, fall back to legacy AGENT365_* names for backward
     compatibility with hand-edited or older .env files.

3. Optional observability feature flags (parity with Python sample)
   - ENABLE_A365_OBSERVABILITY (default true) — master switch; false skips
     useMicrosoftOpenTelemetry() entirely.
   - ENABLE_A365_OBSERVABILITY_EXPORTER (default false) — when false, spans
     are produced but go only to the console exporter; set to true to upload
     to the A365 observability backend.

.env.template and README.md are updated to document Foundry support, both
canonical and legacy env-var names side-by-side, and the observability flags.

Validation:
- End-to-end run against a Foundry account with a fresh agent identity:
  - chat.completions returned HTTP 200 (Foundry path /openai/v1).
  - 3-hop FMI token chain registered initial + refresh tokens.
  - Span tree invoke_agent -> Chat -> execute_tool with matching traceId.
  - A365 backend export succeeded (correlation IDs captured).
  - HTTP /api/health returns 200, / returns 200, /nonexistent returns 404.
  - Heartbeat fires every 60 s; SIGINT triggers graceful shutdown.
- Legacy AGENT365_* env-var fallback verified by removing canonical names.
- No secrets, GUIDs, or API keys land in the diff (.env and a365.*config.json
  are in root .gitignore).
@Yogeshp-MSFT Yogeshp-MSFT force-pushed the nodejs/foundry-and-observability-support branch from d4c9434 to e666c80 Compare June 17, 2026 08:56
Addresses the 4 review comments on PR microsoft#323:

1. URL parsing safety — wrap `new URL(config.endpoint)` in try/catch and validate
   that the parsed URL has an http(s) scheme and a host. Misconfigured values
   now produce a clear "must be an absolute URL" error instead of a confusing
   TypeError at startup.

2. Drop the `^preview$` apiVersion sentinel — it never matched the documented
   examples (`2024-08-01-preview`, `2025-01-01-preview`). Foundry detection now
   relies entirely on the endpoint hostname, which is the documented and
   predictable signal.

3. Make `apiVersion` optional in `TrendingServiceConfig` — defaults to
   `2024-10-21` inside `startTrendingService()` so the exported interface is no
   longer a breaking change for external callers, while preserving the
   environment-driven override path through `src/index.ts`.

4. Document why the Foundry path passes the API key via both `apiKey` and
   `defaultHeaders["api-key"]` — the SDK requires `apiKey` on construction;
   Foundry uses the `api-key` header for auth and ignores the resulting
   `Authorization: Bearer` header.

5. Flip `.env.template` `ENABLE_A365_OBSERVABILITY_EXPORTER` default to `false`
   to match the runtime default and the README. Added a comment pointing users
   at `true` as the explicit opt-in once credentials are configured, so
   copying the template no longer silently uploads traces.
@Yogeshp-MSFT Yogeshp-MSFT force-pushed the nodejs/foundry-and-observability-support branch from ecac9e4 to 659a62e Compare June 17, 2026 09:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants