Skip to content

feat: add Azure Claude (AI Foundry) onboarding path#47181

Open
LazarusStack wants to merge 1 commit intoopenclaw:mainfrom
LazarusStack:main
Open

feat: add Azure Claude (AI Foundry) onboarding path#47181
LazarusStack wants to merge 1 commit intoopenclaw:mainfrom
LazarusStack:main

Conversation

@LazarusStack
Copy link
Copy Markdown

@LazarusStack LazarusStack commented Mar 15, 2026

Summary

  • Problem: Users deploying Claude via Azure AI Foundry have no onboarding path — they must manually configure provider settings, auth profiles, and model refs.
  • Why it matters: Azure Claude is a common enterprise deployment target; first-class onboarding removes friction for these users.
  • What changed: Added anthropic-azure-api-key as a new auth choice with interactive and non-interactive flows (resource/URL prompt, model picker, API key storage, config wiring).
  • What did NOT change: No changes to existing Anthropic direct API flows, no new runtime dependencies, no changes to gateway or startup critical path.

Change Type (select all)

  • Feature
  • Docs

Scope (select all touched areas)

  • Auth / tokens
  • UI / DX

User-visible / Behavior Changes

  • New auth choice anthropic-azure-api-key appears in the onboarding provider picker under the Anthropic group
  • New CLI flags: --anthropic-azure-api-key, --anthropic-azure-base-url, --anthropic-azure-model-id
  • New env vars supported: ANTHROPIC_FOUNDRY_API_KEY, AZURE_CLAUDE_API_KEY, ANTHROPIC_FOUNDRY_BASE_URL, AZURE_CLAUDE_BASE_URL, ANTHROPIC_FOUNDRY_RESOURCE, AZURE_CLAUDE_RESOURCE
  • Invalid resource names (e.g. fabric_hub with underscores) are rejected with a clear error instead of silently stripped

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? Yes — new setAnthropicAzureApiKey stores Azure API keys using the existing auth profile credential infrastructure (same pattern as all other providers)
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • Mitigation: Uses the same SecretInput and AuthProfileStore infrastructure as existing providers; no new storage mechanisms.

Repro + Verification

Steps

# Interactive
openclaw onboard --auth-choice anthropic-azure-api-key

# Non-interactive
openclaw onboard --non-interactive --accept-risk \
  --auth-choice anthropic-azure-api-key \
  --anthropic-azure-base-url fabric-hub \
  --anthropic-azure-model-id claude-sonnet-4-6 \
  --anthropic-azure-api-key "$ANTHROPIC_FOUNDRY_API_KEY"

Evidence

  • 7/7 unit tests pass (src/commands/anthropic-azure-utils.test.ts)
  • Non-interactive provider auth test passes (src/commands/onboard-non-interactive.provider-auth.test.ts)
  • Invalid character rejection test covers the review feedback fix

Human Verification (required)

  • Verified: Interactive and non-interactive onboarding flows, resource name validation, URL normalization, env var resolution
  • Edge cases: Invalid characters in resource names, missing base URL, full URL vs bare resource name, trailing slashes
  • Not verified: End-to-end Azure AI Foundry API calls (requires Azure credentials)

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? Yes — new optional env vars and config keys (additive only)
  • Migration needed? No

Failure Recovery (if this breaks)

  • How to disable/revert: Revert this commit; Azure choice disappears from picker, no other flows affected
  • Known bad symptoms: None expected — isolated to Azure auth choice path

Risks and Mitigations

  • Risk: Azure API key storage uses a new provider ID (anthropic-azure)
    • Mitigation: Follows exact same auth profile pattern as all existing providers

@LazarusStack LazarusStack requested a review from a team as a code owner March 15, 2026 10:14
@openclaw-barnacle openclaw-barnacle bot added docs Improvements or additions to documentation cli CLI command changes commands Command implementations size: L labels Mar 15, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 371ae59ce5

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +81 to +85
const manifestRegistry = loadPluginManifestRegistry({
config: cfg,
workspaceDir: params.workspaceDir,
env,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Derive onboarding choices from loaded providers

resolveProviderWizardOptions now builds auth choices directly from manifest records, so it no longer verifies that the corresponding provider actually loads. In this state, plugins with valid openclaw.plugin.json but load/runtime failures are still shown, and plugins that only expose wizard metadata via registerProvider(...).wizard are omitted; both cases desynchronize the prompt from applyAuthChoiceLoadedPluginProvider, which resolves against resolvePluginProviders and can return null (silent no-op) for a selected choice.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This file is no longer modified in this PR — no longer applicable.

Comment on lines +130 to +134
const manifestRegistry = loadPluginManifestRegistry({
config: cfg,
workspaceDir: params.workspaceDir,
env,
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Derive model-picker setup entries from loaded providers

resolveProviderModelPickerEntries has the same manifest-only source of truth, so model-setup options can be presented for providers that are not actually loadable at runtime. When the user selects one of these entries, promptDefaultModel resolves choices via resolvePluginProviders/resolveProviderPluginChoice and can fail to resolve the selection, causing the setup action to do nothing despite the option being offered.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This file is no longer modified in this PR — no longer applicable.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Mar 15, 2026

Greptile Summary

This PR adds Azure AI Foundry (Azure Claude) as a new auth option alongside the existing Anthropic choices, and improves gateway startup time by replacing the TypeScript-compiled plugin-loading path with a JSON-manifest fast path for resolving onboarding wizard entries.

Key changes:

  • New anthropic-azure-utils.ts module handles URL normalization, resource-name extraction, and env-var resolution for Azure AI Foundry endpoints.
  • auth-choice.apply.anthropic.ts adds the anthropic-azure-api-key branch with interactive and non-interactive flows; credentials are stored with baseUrl/modelId/resource metadata under the anthropic-azure:default profile.
  • provider-wizard.ts is refactored to read wizard.onboarding and wizard.modelPicker directly from JSON manifests (avoiding jiti TypeScript compilation on startup); bundled plugins (vllm, sglang, ollama) have their wizard sections migrated to JSON.
  • manifest-registry.ts exposes wizard in PluginManifestRecord to support the above.

Issues found:

  • normalizeAnthropicAzureBaseUrl silently strips non-[a-z0-9-] characters (e.g. underscore → nothing), so a typo like fabric_hub silently resolves to the wrong endpoint fabrichub.services.ai.azure.com instead of raising a validation error.
  • The provider-wizard.ts fast-path is a breaking change for any third-party plugin that declares wizard.onboarding only in TypeScript — such plugins will silently disappear from the auth choice list with no warning or diagnostic. The PR description does not document this as a breaking change.
  • The it.each failure matrix for ref input-mode fast-fail is missing a case for anthropic-azure-api-key.

Confidence Score: 3/5

  • Mostly safe to merge for built-in providers; the silent URL corruption bug and undocumented plugin breaking change warrant fixes before landing.
  • The core Azure auth flow, credential storage, and non-interactive path are well-implemented and tested. However, the silent character-stripping in normalizeAnthropicAzureBaseUrl can route users to a completely wrong Azure endpoint without any error, and the provider-wizard.ts refactor is a silent breaking change for third-party plugins — neither issue is documented in the PR description.
  • src/commands/anthropic-azure-utils.ts (silent resource name corruption) and src/plugins/provider-wizard.ts (undocumented breaking change for third-party plugins)

Comments Outside Diff (1)

  1. src/commands/onboard-non-interactive.provider-auth.test.ts, line 429-478 (link)

    Missing anthropic-azure-api-key in the ref-mode failure matrix

    The it.each table covers the case where a provider flag is supplied alongside ref input mode without the corresponding env var set, verifying the fast-fail behavior. The new anthropic-azure-api-key auth choice is absent from this table, leaving that code path without test coverage.

    Adding an entry for anthropicAzureApiKey / --anthropic-azure-api-key / ANTHROPIC_FOUNDRY_API_KEY would bring it in line with the other providers tested here.

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: src/commands/onboard-non-interactive.provider-auth.test.ts
    Line: 429-478
    
    Comment:
    **Missing `anthropic-azure-api-key` in the ref-mode failure matrix**
    
    The `it.each` table covers the case where a provider flag is supplied alongside `ref` input mode without the corresponding env var set, verifying the fast-fail behavior. The new `anthropic-azure-api-key` auth choice is absent from this table, leaving that code path without test coverage.
    
    Adding an entry for `anthropicAzureApiKey` / `--anthropic-azure-api-key` / `ANTHROPIC_FOUNDRY_API_KEY` would bring it in line with the other providers tested here.
    
    How can I resolve this? If you propose a fix, please make it concise.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/commands/anthropic-azure-utils.ts
Line: 66-70

Comment:
**Silent character stripping produces a wrong endpoint**

Invalid characters in a resource name are silently dropped rather than rejected. For example, a user providing `fabric_hub` (underscore) — a very common typo for `fabric-hub` — gets transformed to `fabrichub`, which resolves to the completely different endpoint `fabrichub.services.ai.azure.com`. The user receives no warning and will get confusing auth errors instead of a clear input-validation message.

A safer approach is to reject the input when non-`[a-z0-9-]` characters remain after lowercasing:

```suggestion
  const normalizedResource = raw.toLowerCase();
  if (/[^a-z0-9-]/.test(normalizedResource)) {
    throw new Error(
      `Azure Claude resource name "${raw}" contains invalid characters. ` +
        "Only lowercase letters, numbers, and hyphens are allowed (e.g. fabric-hub).",
    );
  }
  if (!normalizedResource) {
    throw new Error("Azure Claude resource name must contain alphanumeric characters or hyphens.");
  }
  return `https://${normalizedResource}${ANTHROPIC_AZURE_HOST_SUFFIX}${ANTHROPIC_AZURE_API_SUFFIX}`;
```

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/plugins/provider-wizard.ts
Line: 71-110

Comment:
**Breaking change for plugins that declare `wizard.onboarding` only in TypeScript**

The old implementation called `resolvePluginProviders()`, which compiled and evaluated each plugin's TypeScript entry point so that `provider.wizard?.onboarding` could be read from the runtime object. The new fast path reads `record.wizard?.onboarding` exclusively from the JSON manifest, bypassing TypeScript entirely.

Any third-party (or first-party) plugin that declared `wizard.onboarding` only in its TypeScript entry and did **not** mirror it in `openclaw.plugin.json` will now silently disappear from the auth choice list. The bundled plugins (vllm, sglang, ollama) are updated in this very PR, but custom/third-party plugins have no migration path and no warning.

Consider adding a diagnostic entry when a plugin has a TypeScript-defined `wizard.onboarding` but lacks the JSON `wizard` field, or at minimum documenting this as a breaking change in the PR description and migration guide.

How can I resolve this? If you propose a fix, please make it concise.

---

This is a comment left during a code review.
Path: src/commands/onboard-non-interactive.provider-auth.test.ts
Line: 429-478

Comment:
**Missing `anthropic-azure-api-key` in the ref-mode failure matrix**

The `it.each` table covers the case where a provider flag is supplied alongside `ref` input mode without the corresponding env var set, verifying the fast-fail behavior. The new `anthropic-azure-api-key` auth choice is absent from this table, leaving that code path without test coverage.

Adding an entry for `anthropicAzureApiKey` / `--anthropic-azure-api-key` / `ANTHROPIC_FOUNDRY_API_KEY` would bring it in line with the other providers tested here.

How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 371ae59

Comment on lines +66 to +70
const normalizedResource = raw.toLowerCase().replace(/[^a-z0-9-]/g, "");
if (!normalizedResource) {
throw new Error("Azure Claude resource name must contain alphanumeric characters or hyphens.");
}
return `https://${normalizedResource}${ANTHROPIC_AZURE_HOST_SUFFIX}${ANTHROPIC_AZURE_API_SUFFIX}`;
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.

Silent character stripping produces a wrong endpoint

Invalid characters in a resource name are silently dropped rather than rejected. For example, a user providing fabric_hub (underscore) — a very common typo for fabric-hub — gets transformed to fabrichub, which resolves to the completely different endpoint fabrichub.services.ai.azure.com. The user receives no warning and will get confusing auth errors instead of a clear input-validation message.

A safer approach is to reject the input when non-[a-z0-9-] characters remain after lowercasing:

Suggested change
const normalizedResource = raw.toLowerCase().replace(/[^a-z0-9-]/g, "");
if (!normalizedResource) {
throw new Error("Azure Claude resource name must contain alphanumeric characters or hyphens.");
}
return `https://${normalizedResource}${ANTHROPIC_AZURE_HOST_SUFFIX}${ANTHROPIC_AZURE_API_SUFFIX}`;
const normalizedResource = raw.toLowerCase();
if (/[^a-z0-9-]/.test(normalizedResource)) {
throw new Error(
`Azure Claude resource name "${raw}" contains invalid characters. ` +
"Only lowercase letters, numbers, and hyphens are allowed (e.g. fabric-hub).",
);
}
if (!normalizedResource) {
throw new Error("Azure Claude resource name must contain alphanumeric characters or hyphens.");
}
return `https://${normalizedResource}${ANTHROPIC_AZURE_HOST_SUFFIX}${ANTHROPIC_AZURE_API_SUFFIX}`;
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/commands/anthropic-azure-utils.ts
Line: 66-70

Comment:
**Silent character stripping produces a wrong endpoint**

Invalid characters in a resource name are silently dropped rather than rejected. For example, a user providing `fabric_hub` (underscore) — a very common typo for `fabric-hub` — gets transformed to `fabrichub`, which resolves to the completely different endpoint `fabrichub.services.ai.azure.com`. The user receives no warning and will get confusing auth errors instead of a clear input-validation message.

A safer approach is to reject the input when non-`[a-z0-9-]` characters remain after lowercasing:

```suggestion
  const normalizedResource = raw.toLowerCase();
  if (/[^a-z0-9-]/.test(normalizedResource)) {
    throw new Error(
      `Azure Claude resource name "${raw}" contains invalid characters. ` +
        "Only lowercase letters, numbers, and hyphens are allowed (e.g. fabric-hub).",
    );
  }
  if (!normalizedResource) {
    throw new Error("Azure Claude resource name must contain alphanumeric characters or hyphens.");
  }
  return `https://${normalizedResource}${ANTHROPIC_AZURE_HOST_SUFFIX}${ANTHROPIC_AZURE_API_SUFFIX}`;
```

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — resource names with invalid characters are now rejected with a descriptive error message instead of being silently stripped. Added a regression test covering fabric_hub and space-containing inputs.

Comment on lines +71 to +110
workspaceDir?: string;
env?: NodeJS.ProcessEnv;
}): ProviderWizardOption[] {
const providers = resolvePluginProviders(params);
// Fast path: read wizard metadata from manifests (JSON only, no jiti compilation).
// Plugins that want to appear in the auth choice must declare wizard.onboarding in their
// openclaw.plugin.json manifest. This avoids blocking synchronous TypeScript compilation
// via jiti on every onboarding auth choice prompt render.
const env = params.env ?? process.env;
const cfg = params.config ?? {};
const normalized = normalizePluginsConfig(cfg.plugins);
const manifestRegistry = loadPluginManifestRegistry({
config: cfg,
workspaceDir: params.workspaceDir,
env,
});
const options: ProviderWizardOption[] = [];

for (const provider of providers) {
const wizard = provider.wizard?.onboarding;
if (!wizard) {
for (const record of manifestRegistry.plugins) {
const onboarding = record.wizard?.onboarding;
if (!onboarding) {
continue;
}
const explicitMethod = resolveMethodById(provider, wizard.methodId);
if (explicitMethod) {
options.push(
buildOnboardingOptionForMethod({
provider,
wizard,
method: explicitMethod,
value: resolveWizardOnboardingChoiceId(provider, wizard),
}),
);
const enableState = resolveEffectiveEnableState({
id: record.id,
origin: record.origin,
config: normalized,
rootConfig: cfg,
});
if (!enableState.enabled) {
continue;
}

for (const method of provider.auth) {
options.push(
buildOnboardingOptionForMethod({
provider,
wizard,
method,
value: buildProviderPluginMethodChoice(provider.id, method.id),
}),
);
}
const choiceId = onboarding.choiceId?.trim();
const methodId = onboarding.methodId?.trim();
const value = choiceId
? normalizeChoiceId(choiceId)
: methodId
? buildProviderPluginMethodChoice(record.id, methodId)
: record.id;
const groupId = onboarding.groupId?.trim() || record.id;
options.push({
value,
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.

Breaking change for plugins that declare wizard.onboarding only in TypeScript

The old implementation called resolvePluginProviders(), which compiled and evaluated each plugin's TypeScript entry point so that provider.wizard?.onboarding could be read from the runtime object. The new fast path reads record.wizard?.onboarding exclusively from the JSON manifest, bypassing TypeScript entirely.

Any third-party (or first-party) plugin that declared wizard.onboarding only in its TypeScript entry and did not mirror it in openclaw.plugin.json will now silently disappear from the auth choice list. The bundled plugins (vllm, sglang, ollama) are updated in this very PR, but custom/third-party plugins have no migration path and no warning.

Consider adding a diagnostic entry when a plugin has a TypeScript-defined wizard.onboarding but lacks the JSON wizard field, or at minimum documenting this as a breaking change in the PR description and migration guide.

Prompt To Fix With AI
This is a comment left during a code review.
Path: src/plugins/provider-wizard.ts
Line: 71-110

Comment:
**Breaking change for plugins that declare `wizard.onboarding` only in TypeScript**

The old implementation called `resolvePluginProviders()`, which compiled and evaluated each plugin's TypeScript entry point so that `provider.wizard?.onboarding` could be read from the runtime object. The new fast path reads `record.wizard?.onboarding` exclusively from the JSON manifest, bypassing TypeScript entirely.

Any third-party (or first-party) plugin that declared `wizard.onboarding` only in its TypeScript entry and did **not** mirror it in `openclaw.plugin.json` will now silently disappear from the auth choice list. The bundled plugins (vllm, sglang, ollama) are updated in this very PR, but custom/third-party plugins have no migration path and no warning.

Consider adding a diagnostic entry when a plugin has a TypeScript-defined `wizard.onboarding` but lacks the JSON `wizard` field, or at minimum documenting this as a breaking change in the PR description and migration guide.

How can I resolve this? If you propose a fix, please make it concise.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This file is no longer modified in this PR — the setuponboarding rename was from merge commits in the old branch history, not part of this feature. The rebased branch only touches Azure-specific files.

@LazarusStack LazarusStack force-pushed the main branch 2 times, most recently from 84cc578 to cdecee6 Compare March 16, 2026 07:27
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cdecee6e9f

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

};

await ensureApiKeyFromOptionEnvOrPrompt({
token: params.opts?.anthropicAzureApiKey,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use generic --token input for apiKey-mapped Azure auth

When authChoice=apiKey with tokenProvider=anthropic-azure, normalizeApiKeyTokenProviderAuthChoice routes into this Azure branch, but the API key source is hardcoded to opts.anthropicAzureApiKey instead of opts.token. As a result, flows like --auth-choice apiKey --token-provider anthropic-azure --token ... ignore the supplied token and fall back to env/prompt, which breaks scripted onboarding and is inconsistent with other apiKey-mapped providers.

Useful? React with 👍 / 👎.

@openclaw-barnacle openclaw-barnacle bot added the app: web-ui App: web-ui label Mar 16, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ddc21e48d3

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +260 to +262
if (params.setDefaultModel) {
nextConfig = applyAgentDefaultModelPrimary(nextConfig, `anthropic-azure/${resolvedModelId}`);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Set agent override when Azure auth skips global default

In applyAuthChoiceApiProviders, the new anthropic-azure-api-key path only applies applyAgentDefaultModelPrimary(...) when params.setDefaultModel is true and never assigns agentModelOverride otherwise. Callers that intentionally pass setDefaultModel: false (for example agent-scoped setup flows) depend on agentModelOverride to set that agent’s model, so choosing Azure Claude can silently leave the agent on its previous provider/model despite writing Azure auth/config, leading to model/auth mismatches at runtime.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed — replaced the manual applyAgentDefaultModelPrimary call with applyProviderDefaultModel() (the shared helper from createAuthChoiceDefaultModelApplierForMutableState). This correctly sets agentModelOverride for agent-scoped flows when setDefaultModel is false, matching the pattern used by other providers (e.g. LiteLLM).

@LazarusStack
Copy link
Copy Markdown
Author

CI Status Update

All failing CI checks match current main branch failures — verified by comparing job logs side-by-side:

Check Status Notes
check (typecheck) Fail Same bonjour.ts + auth-choice.contract.test.ts errors as main
startup-memory Fail main uses 907 MB with 925 MB limit (17 MB headroom); flaky on PRs
channels / extensions / windows-5 Fail Pre-existing on main
install-smoke Fail Matrix extension type errors, pre-existing on main
check-docs Pass Fixed duplicate heading in this PR
node tests (1/2, 2/2) Pass Core test suites pass

Changes made after review feedback

  1. Silent character stripping fix — Resource name validation now rejects invalid characters (e.g. fabric_hub) with a clear error message instead of silently stripping them to fabrichub. Added regression test.

  2. provider-wizard.ts comment — The referenced manifest-only fast path was not part of this PR's changes. The setuponboarding rename came in via merge commits and has been removed in the cleaned-up branch.

  3. Lazy-loaded Azure utilsanthropic-azure-utils.js is dynamically imported only when the Azure auth choice is selected, keeping it off the startup critical path.

@LazarusStack LazarusStack force-pushed the main branch 2 times, most recently from 81568e5 to 4c78be2 Compare March 16, 2026 08:34
@openclaw-barnacle openclaw-barnacle bot removed the app: web-ui App: web-ui label Mar 16, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 4c78be2473

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +60 to +62
const normalizedPath = basePath.endsWith(ANTHROPIC_AZURE_API_SUFFIX)
? basePath
: `${basePath}${ANTHROPIC_AZURE_API_SUFFIX}`;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject invalid Azure endpoint paths during URL normalization

normalizeAnthropicAzureBaseUrl currently appends "/anthropic" to any existing path that does not already end with that suffix, so inputs like https://<resource>.services.ai.azure.com/anthropic/v1 are normalized to .../anthropic/v1/anthropic and then saved into provider config. That produces a malformed base URL which will make subsequent Anthropic requests fail at runtime instead of failing fast during onboarding; the normalizer should reject unexpected path segments (or explicitly canonicalize known variants) rather than concatenating blindly.

Useful? React with 👍 / 👎.

@LazarusStack LazarusStack changed the title Azure claude code auth option added and the gateway startup time decreased feat: add Azure Claude (AI Foundry) onboarding path Mar 16, 2026
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 548fb1c1ef

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +53 to +55
if (!url.hostname.toLowerCase().endsWith(ANTHROPIC_AZURE_HOST_SUFFIX)) {
throw new Error(
`Azure Claude endpoint host must end with "${ANTHROPIC_AZURE_HOST_SUFFIX}". Received ${url.hostname}.`,
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject invalid Azure resource hosts in URL input

When users pass a full URL, normalization only checks that the hostname ends with .services.ai.azure.com, so invalid resource labels like fabric_hub.services.ai.azure.com are accepted even though the resource-name path rejects underscores. This stores an endpoint that cannot be resolved by Azure and pushes the failure to runtime requests instead of failing fast during onboarding; the URL branch should validate the resource label with the same character rules used for bare resource names.

Useful? React with 👍 / 👎.

Add Azure Claude as a provider option in onboarding, supporting:
- Interactive and non-interactive auth flows with API key, base URL, and model selection
- Resource name validation that rejects invalid characters with clear error messages
- Lazy-loaded Azure utils to avoid startup memory impact
- CLI flags: --anthropic-azure-api-key, --anthropic-azure-base-url, --anthropic-azure-model-id
- Environment variable support: ANTHROPIC_FOUNDRY_API_KEY, AZURE_CLAUDE_API_KEY,
  ANTHROPIC_FOUNDRY_BASE_URL, AZURE_CLAUDE_BASE_URL, ANTHROPIC_FOUNDRY_RESOURCE, AZURE_CLAUDE_RESOURCE

Also fixes ChannelMessageCapability import in contracts/suites.ts (pre-existing upstream type error).
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9b06ad46bb

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment on lines +60 to +63
const normalizedPath = basePath.endsWith(ANTHROPIC_AZURE_API_SUFFIX)
? basePath
: `${basePath}${ANTHROPIC_AZURE_API_SUFFIX}`;
const finalPath = normalizedPath || ANTHROPIC_AZURE_API_SUFFIX;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reject unsupported Azure endpoint paths

When the input is a full URL, the normalizer appends "/anthropic" to any pathname that does not already end with that suffix, so values like https://<resource>.services.ai.azure.com/anthropic/v1 become .../anthropic/v1/anthropic. That produces a malformed provider baseUrl and shifts the failure to runtime requests instead of failing fast during onboarding.

Useful? React with 👍 / 👎.

Comment on lines +53 to +56
if (!url.hostname.toLowerCase().endsWith(ANTHROPIC_AZURE_HOST_SUFFIX)) {
throw new Error(
`Azure Claude endpoint host must end with "${ANTHROPIC_AZURE_HOST_SUFFIX}". Received ${url.hostname}.`,
);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Validate Azure resource label in URL host

The URL branch only checks endsWith(".services.ai.azure.com"), so hosts with invalid resource labels (for example underscores) pass validation and are persisted as endpoints. This allows clearly invalid Azure resource hosts to be accepted in onboarding and fail later at request time rather than being rejected immediately.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cli CLI command changes commands Command implementations docs Improvements or additions to documentation size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant