Skip to content

feat(providers): implement Azure OpenAI provider with DIAL compatibility#365

Open
Ratgor wants to merge 2 commits into
codemie-ai:mainfrom
Ratgor:feat/azure-openai-provider
Open

feat(providers): implement Azure OpenAI provider with DIAL compatibility#365
Ratgor wants to merge 2 commits into
codemie-ai:mainfrom
Ratgor:feat/azure-openai-provider

Conversation

@Ratgor

@Ratgor Ratgor commented Jun 16, 2026

Copy link
Copy Markdown

Summary

Implements the Azure OpenAI provider with specific compatibility for the DIAL gateway, including payload sanitization to prevent API errors.

Changes

  • Added Azure OpenAI provider implementation.
  • Implemented AzureDialSanitizer to remove incompatible fields (e.g., cache_control) from requests.
  • Added comprehensive unit and integration tests for the provider and sanitizer.
  • Updated provider metadata and setup steps.

Test Plan

  • Unit tests for Azure OpenAI provider and sanitizer.
  • Integration tests for DIAL compatibility.
  • Manual testing with Azure OpenAI API.

Checklist

  • Code follows style guide.
  • All tests pass.
  • Documentation updated.
  • No merge conflicts.

AliaksandrTsurko added 2 commits June 15, 2026 23:57
…ity and payload sanitization

Details:
- Add Azure OpenAI provider template and setup steps;
- Implement comprehensive payload sanitization for DIAL endpoints to prevent schema errors;
- Refine model family detection for vendor-prefixed IDs;
- General cleanup and standards validation.

@8nevil8 8nevil8 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Code Review — feat(providers): Azure OpenAI + DIAL compatibility

Decision: REQUEST CHANGES

The core architecture is solid — per-deployment provider entries, api-key header injection, Claude-specific beforeRun hook disabling prompt caching and thinking, and the DIAL sanitizer plugin are all well-designed and well-documented. The blocking issues are a CI gate failure from test fixture strings, a UX bug (Russian-language string in English CLI output), and several logging-policy violations.


CR-001 — CRITICAL: Test fixture API key values trigger Gitleaks — CI is blocked

File: src/providers/plugins/azure-openai/__tests__/azure-openai.template.test.ts lines 20, 22, 24

Gitleaks generic-api-key rule matched 3 times on the string 'test-api-key-1234567890' assigned to AZURE_OPENAI_API_KEY, CODEMIE_API_KEY, and ANTHROPIC_AUTH_TOKEN in makeEnv(). The Secrets Detection CI gate fails, which causes Build and Test to skip — no test execution evidence exists for this PR.

Fix: Replace with a placeholder that won't match entropy rules, e.g. 'PLACEHOLDER-KEY-FOR-TESTING-ONLY' or 'test-key-xxxxx'. Check for the same pattern in any other test files added in this PR.


CR-002 — MAJOR: dial-model-integrity.ts uses console.log/console.error throughout

File: src/utils/dial-model-integrity.ts

The entire file uses console.log and console.error for all output. Per development-practices.md and code-quality.md, production code must use logger.* (debug/warn/error) — console.log is explicitly prohibited for diagnostics. The pre-commit checklist item is "No console.log() left in code".

Fix: Replace internal diagnostic calls with logger.info/logger.warn/logger.error. User-facing table output (the summary printed to stdout) can remain as console.log, but non-diagnostic messages must go through the logger.


CR-003 — MAJOR: Russian-language string in --test-dial CLI output + console.log in CLI command

File: src/cli/commands/doctor/index.ts lines ~1525–1528

The --test-dial error branch emits a mixed Russian/English message via console.log:

dial integration test: active profile provider не DIAL/azure-openai. Выберите профиль DIAL через codemie profile switch или setup.

This will render as unreadable text for all non-Russian users. Additionally, console.log is used in a CLI command instead of the project's logger or chalk-formatted output.

Fix: Replace with English: 'The active profile provider is not DIAL/azure-openai. Switch to a DIAL profile via "codemie profile switch" or run "codemie setup".' Move to logger.warn or a proper CLI error output pattern.


CR-004 — MAJOR: Bare Error thrown in auto-retry-sanitizer.ts

File: src/agents/plugins/azure-dial-sanitizer/auto-retry-sanitizer.ts line 315

requestWithSanitizerRetry throws new Error('[DIAL Retry] ...'). Per development-practices.md, project code must use specific error classes from src/utils/errors.ts (e.g. ToolExecutionError), not bare Error.

Fix:

import { ToolExecutionError } from '../../../utils/errors.js';
// ...
throw new ToolExecutionError(`[DIAL Retry] Request failed after sanitize retry: ${err2?.message || err2}`);

CR-005 — MAJOR: console.error added in setup.ts model-fetch catch block

File: src/cli/commands/setup.ts line ~560

The new console.error(chalk.red('Failed to fetch models'), error) bypasses the logger (no log-level control, no file output, raw error object may contain sensitive request details).

Fix: Replace with logger.warn('[setup] Could not fetch models', { error: error instanceof Error ? error.message : String(error) }) to match the surrounding code and the project logging standard.


CR-006 — MAJOR: Indentation defect in buildOpenCodeConfig() in codemie-code.plugin.ts

File: src/agents/plugins/codemie-code.plugin.ts lines ~776–782

The baseEnabledProviders and enabledProviders declarations and their if/else block are indented at column 0 inside the function body, while the surrounding code uses 2-space indentation. This will fail the lint-staged ESLint run.

Fix: Re-indent the block to match the 2-space indentation of the enclosing function body.


CR-007 — MAJOR: Exported function in auto-retry-sanitizer.ts missing JSDoc

File: src/agents/plugins/azure-dial-sanitizer/auto-retry-sanitizer.ts line ~298

requestWithSanitizerRetry is an exported public API using any-typed parameters. Per code-quality.md, all exported functions need explicit return types (present but typed Promise<any>) and JSDoc on all public APIs — especially when any is used, which the guide requires to be documented with a rationale.

Fix: Add a JSDoc block explaining the any parameter types and what the function guarantees.


CR-008 — MINOR: Source-level AzureDial / azure-dial-sanitizer naming is inconsistent with the provider name azure-openai

Files:

  • src/agents/plugins/azure-dial-sanitizer/ (directory)
  • azure-dial-sanitizer-source.ts: AzureDialSanitizerPlugin, sanitizeAzureDialPayload, AZURE_DIAL_SANITIZER_PLUGIN_SOURCE
  • inject-sanitizer.ts: getAzureDialSanitizerPluginUrl, cleanupAzureDialSanitizerPlugin

Every other artifact in this PR uses AzureOpenAI naming (AzureOpenAITemplate, AzureOpenAIHealthCheck, AzureOpenAIModelProxy, provider name 'azure-openai'). The DIAL suffix leaks an EPAM-specific implementation detail into public source identifiers; the sanitizer is equally necessary for plain Azure OpenAI endpoints, not only DIAL gateways.

Important distinction — what must stay as azure-dial-:
The runtime OpenCode provider key prefix (azure-dial-{modelId}, built by buildAzureOpenAIProviders()) and the in-plugin guard pid.startsWith("azure-dial-") are intentionally coupled and must remain in sync. That is an internal OpenCode config namespace that users never see, and the existing comment in buildAzureOpenAIProviders() explains the convention clearly — no change needed there.

What should be renamed (source-level identifiers only):

Current Suggested
azure-dial-sanitizer/ (directory) azure-openai-sanitizer/
AzureDialSanitizerPlugin AzureOpenAISanitizerPlugin
sanitizeAzureDialPayload sanitizeAzureOpenAIPayload
AZURE_DIAL_SANITIZER_PLUGIN_SOURCE AZURE_OPENAI_SANITIZER_PLUGIN_SOURCE
getAzureDialSanitizerPluginUrl getAzureOpenAISanitizerPluginUrl
cleanupAzureDialSanitizerPlugin cleanupAzureOpenAISanitizerPlugin

This keeps source-level naming consistent with the registered provider name and removes the EPAM DIAL-specific term from the public module API. The runtime azure-dial-* key convention is a separate concern and stays unchanged.

@codemie-ai

Copy link
Copy Markdown
Owner

[AUTO_CLOSE_WARNING] ⏰ This pull request is older than 14 days and will be automatically closed in 16 more days (when it reaches 30 days old)! To maintain this PR, either convert it to Draft or complete your changes and merge.

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.

3 participants