Skip to content

feat(sleep): support OpenAI-compatible endpoints (DeepSeek, vLLM) in azure_openai backend#129

Merged
Yif-Yang merged 2 commits into
microsoft:mainfrom
Alphaxalchemy:feat/openai-compatible-endpoints
Jul 14, 2026
Merged

feat(sleep): support OpenAI-compatible endpoints (DeepSeek, vLLM) in azure_openai backend#129
Yif-Yang merged 2 commits into
microsoft:mainfrom
Alphaxalchemy:feat/openai-compatible-endpoints

Conversation

@Alphaxalchemy

@Alphaxalchemy Alphaxalchemy commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

What

Enables the SkillOpt-Sleep azure_openai backend to drive any OpenAI-compatible chat-completions endpoint — e.g. DeepSeek's hosted API or a self-hosted vLLM/Ollama server — alongside the existing native Azure OpenAI managed-identity path. The default Azure path is unchanged and fully backward-compatible.

Why

Pointing the azure_openai backend at a non-Azure endpoint was impossible: the endpoint was resolved only from a hardcoded _AZURE_ENDPOINTS table, and _get_client() always built an AzureOpenAI client. That client rewrites request URLs with Azure-only structure (?api-version=… query params + deployment path segments), which non-Azure OpenAI-compatible servers reject with 404 Resource not found. SkillOpt-Sleep then gets an empty response, the judge scores it 0.0, and every night reports baseline 0.0 → candidate 0.0 with no usable diagnostic.

Notably, the sibling module skillopt/model/azure_openai.py already supports an openai_compatible auth mode; this change brings skillopt_sleep/backend.py in line with it.

What changed (skillopt_sleep/backend.py, +48 / −14)

  1. Endpoint resolution honors AZURE_OPENAI_ENDPOINT — order is now explicit argAZURE_OPENAI_ENDPOINT env → the built-in table.
  2. openai_compatible auth mode — when AZURE_OPENAI_AUTH_MODE=openai_compatible (also compat/openai), _get_client() builds a plain openai.OpenAI(base_url=…) client, avoiding the Azure URL rewriting.
  3. DeepSeek request shape + error surfacing_call() sends max_tokens + extra_body={"thinking": {"type": "enabled"}} for deepseek* deployments, and records the last exception in self.last_call_error so a failed night is diagnosable instead of a silent empty→0.0.

Plus documentation: docs/sleep/openai-compatible-endpoints.md and sanitized docs/sleep/examples/ runner + watchdog scripts showing an Antigravity IDE + DeepSeek integration (no keys, no hardcoded personal paths).

How to test

export AZURE_OPENAI_AUTH_MODE=openai_compatible
export AZURE_OPENAI_ENDPOINT=https://api.deepseek.com
export AZURE_OPENAI_API_KEY=sk-...        # your DeepSeek key
skillopt-sleep run --backend azure_openai --model deepseek-v4-pro --project /path/to/project

To pull this branch locally:

git remote add alphax https://github.com/Alphaxalchemy/SkillOpt.git
git fetch alphax feat/openai-compatible-endpoints
git checkout feat/openai-compatible-endpoints

Results (verified on Windows 11, deepseek-v4-pro)

  • Direct backend smoke test returns a live completion — client type OpenAI, no 404, last_call_error empty.
  • A full nightly cycle moved the held-out validation gate 0.250 → 1.000 and accepted a DeepSeek-authored skill edit (accept_new_best); diagnostics.json shows "backend": "azure_openai" with non-zero tokens and empty call_error — a genuine optimization night vs. the prior all-0.0 nights caused by the endpoint bug.
  • A subsequent unattended (watchdog-triggered) night completed the full chain and the gate correctly rejected a non-improving proposal (0.3 → 0.3), confirming normal gate behavior on the new backend.

Notes

  • Backward compatible: with AZURE_OPENAI_AUTH_MODE unset, behavior is identical to before (managed-identity AzureOpenAI).
  • The docs are explicit that there is no native Gemini backend; a Gemini fallback shown in the example runner routes the claude CLI through a local Anthropic-compatible proxy and is documented as illustrative/unverified, not a supported path.

@Alphaxalchemy

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree [company="{ALFRED KOLAKKAL}"]

@Alphaxalchemy

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree company="ALFRED KOLAKKAL"

@Alphaxalchemy

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree

@Alphaxalchemy
Alphaxalchemy force-pushed the feat/openai-compatible-endpoints branch from 38f4880 to f14b802 Compare July 13, 2026 03:04
Let AzureOpenAIBackend drive any OpenAI-compatible chat-completions server
(DeepSeek, self-hosted vLLM/Ollama, ...) alongside native Azure deployments.

- __init__ resolves the endpoint as: explicit arg > AZURE_OPENAI_ENDPOINT env
  > the built-in _AZURE_ENDPOINTS table (previously a non-Azure endpoint could
  not be supplied at all).
- _get_client() builds a plain openai.OpenAI(base_url=...) client when
  AZURE_OPENAI_AUTH_MODE=openai_compatible, matching the auth mode already
  supported by the sibling skillopt/model/azure_openai.py. This avoids the
  AzureOpenAI SDK rewriting request URLs with Azure-only ?api-version= query
  params and deployment path segments, which non-Azure servers reject with 404.
- _call() sends max_tokens + extra_body thinking flag for deepseek* models and
  records the last exception in self.last_call_error so a failed night is
  diagnosable instead of collapsing to a silent empty->0 score.

Adds docs/sleep/openai-compatible-endpoints.md and sanitized example
runner/watchdog scripts documenting an Antigravity + DeepSeek integration.
The default managed-identity Azure path is unchanged.
@Alphaxalchemy
Alphaxalchemy force-pushed the feat/openai-compatible-endpoints branch from f14b802 to af33f6c Compare July 13, 2026 03:43

@Yif-Yang Yif-Yang 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.

Requesting changes because the documented CLI path fails, the watchdog can report false success, error state is inconsistent, the managed-identity endpoint path needs a security guard, and the new behavior has no tests. Please address the detailed maintainer comment above.

@Yif-Yang
Yif-Yang dismissed their stale review July 13, 2026 15:50

Replacing this review with a corrected protocol-scoped review. Azure Responses testing is not required for this OpenAI-compatible Chat Completions contribution.

@Yif-Yang Yif-Yang 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.

Thanks for contributing this — adding standard OpenAI-compatible Chat Completions support to SkillOpt-Sleep is a useful improvement, and your reported DeepSeek end-to-end run is relevant validation for that scope.

A clarification from our side: we do not require this PR to be tested against Azure Responses API. Azure Responses and OpenAI-compatible Chat Completions are different protocols, so forcing an Azure Responses test here would be the wrong acceptance criterion. A compliant OpenAI-compatible endpoint such as DeepSeek or vLLM is the appropriate live smoke test, and the DeepSeek result already described in this PR is sufficient for the live-provider portion.

Before approval, please address this smaller, protocol-scoped set of integration issues:

  1. Expose the feature through the documented CLI path. The documented command uses --backend azure_openai, but that value is currently rejected by the choices in skillopt_sleep/__main__.py.
  2. Propagate failures from the example runner. runner.py ignores the child return code, so watchdog.py can report a failed sleep run as successful.
  3. Make error state reliable. Clear last_call_error after a recovered successful retry, and set a useful diagnostic when all responses are empty.
  4. Keep compatible auth separate from managed identity. A non-Azure custom endpoint should require explicit compatible/API-key auth; setting a custom endpoint must not accidentally send an Azure managed-identity bearer token to an arbitrary host.
  5. Keep generic behavior provider-neutral. The DeepSeek-specific thinking body and hard-coded token limit should be opt-in/configured (or split into a provider-specific follow-up) rather than inferred solely from a model-name substring. The generic path only needs to honor the standard OpenAI-compatible request contract.
  6. Align documentation with implementation. Either implement the optimizer/target-prefixed environment variables claimed by the docs or remove that claim.
  7. Add focused no-network tests for CLI acceptance, compatible-vs-Azure client selection, endpoint/auth handling, request kwargs, retry-success error clearing, empty-response diagnostics, and runner exit-code propagation.

Once these deterministic tests pass along with the full suite, no additional Azure live test is needed. We would be happy to re-review promptly and merge this through your original PR so your authorship and contribution history remain intact.

… kwargs, tests

Addresses maintainer review on the OpenAI-compatible endpoints PR:

1. CLI: accept --backend azure_openai in skillopt_sleep/__main__.py (the
   documented command was rejected by the argparse choices).
2. Example runner: exit with the child's return code so watchdog/supervisors
   see a failed sleep run as a failure.
3. Error state: clear last_call_error when a retry recovers; set an explicit
   "empty response on all N attempts" diagnostic when every attempt returns
   empty text.
4. Security guard: the managed-identity path now refuses to send an Azure AD
   bearer token to any endpoint outside *.openai.azure.com /
   *.cognitiveservices.azure.com — a custom endpoint requires explicit
   AZURE_OPENAI_AUTH_MODE=openai_compatible + API key.
5. Provider-neutral requests: compat mode sends only the standard contract
   (max_tokens, default 8192 via SKILLOPT_SLEEP_COMPAT_MAX_TOKENS);
   provider-specific body fields are opt-in via SKILLOPT_SLEEP_CHAT_EXTRA_BODY
   (JSON) — the deepseek model-name inference is removed.
6. Docs: removed the unimplemented OPTIMIZER_*/TARGET_* env-var claim; added a
   configuration reference matching the implementation exactly.
7. Tests: tests/test_azure_openai_compat.py — 17 deterministic no-network
   unittest cases covering CLI acceptance, compat-vs-Azure client selection,
   endpoint resolution, the credential guard, request kwargs (opt-in extra
   body / token cap), retry-success error clearing, empty-response
   diagnostics, and runner exit-code propagation.

Re-verified live against DeepSeek (deepseek-v4-pro, openai_compatible mode)
after the rework: client type OpenAI, completion returned, no error state.
@Alphaxalchemy

Copy link
Copy Markdown
Contributor Author

Thanks for the fast, clearly-scoped review — all seven items are addressed in 4ff77b7.

  1. CLI pathazure_openai added to the --backend choices in skillopt_sleep/__main__.py; the documented command now parses.
  2. Runner exit codesexamples/runner.py now ends with sys.exit(proc.returncode), so watchdog.py (which already checks the return code) logs a failed sleep run as a failure.
  3. Error statelast_call_error is cleared when a retry recovers, and when every attempt returns empty text it is set to "<deployment>: empty response on all N attempts" so diagnostics distinguish that from a never-called backend.
  4. Credential guard — the managed-identity branch now raises a ValueError (before any azure.identity import) if the endpoint host is outside *.openai.azure.com / *.cognitiveservices.azure.com, so a custom endpoint can never receive an AAD bearer token; the error message points to AZURE_OPENAI_AUTH_MODE=openai_compatible.
  5. Provider-neutral requests — the deepseek model-name inference is removed. Compat mode sends only the standard contract (model, messages, max_tokens — default 8192, configurable via SKILLOPT_SLEEP_COMPAT_MAX_TOKENS); provider-specific body fields are opt-in via SKILLOPT_SLEEP_CHAT_EXTRA_BODY (JSON object passed as extra_body, e.g. DeepSeek's thinking flag). Azure mode is byte-for-byte unchanged (max_completion_tokens=16384).
  6. Docs aligned — the OPTIMIZER_*/TARGET_* claim is removed (the doc now explicitly notes those belong to skillopt.model.azure_openai, not the sleep cycle), and a configuration-reference table matches the implementation exactly.
  7. Teststests/test_azure_openai_compat.py: 17 deterministic, no-network stdlib-unittest cases covering CLI acceptance, compat-vs-Azure client selection, endpoint resolution precedence, the credential guard, request kwargs (opt-in extra body + token-cap override + malformed-JSON handling), retry-success error clearing, empty-response diagnostics, and runner exit-code propagation (both failure and success). The one test that constructs a real openai.OpenAI client is skipped if openai isn't installed, keeping the suite dependency-free.

Verification: the new file passes 17/17; the full suite on this branch shows no regressions vs. a pristine upstream/main run in the same environment (the only errors in both are pre-existing loader failures from test files that import pytest, which isn't in my env). I also re-ran the live DeepSeek smoke test (deepseek-v4-pro, openai_compatible, extra-body via the new env knob) after the rework: client type OpenAI, completion returned, empty error state.

Agreed on scope — no Azure Responses testing was done or claimed for this protocol. Ready for re-review.

@Alphaxalchemy
Alphaxalchemy requested a review from Yif-Yang July 14, 2026 07:28

@Yif-Yang Yif-Yang 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.

Thank you for the careful rework. Commit 4ff77b7 genuinely addresses the seven points from the previous review: the CLI path is reachable, runner failures propagate, error state is reliable, provider-specific fields are opt-in, the docs now match the implementation, and the new focused coverage is useful.

We reran the 17 focused tests and the full suite against current main, and also exercised the plain OpenAI client against a local HTTP server. The OpenAI-compatible request path works. This remains a Chat Completions review; Azure Responses testing is not required.

Two narrowly scoped issues remain before merge:

  1. Managed-identity endpoints must require HTTPS. _is_azure_host() currently validates only the hostname suffix. Consequently http://foo.openai.azure.com passes the guard, and the AzureOpenAI SDK accepts that URL, allowing an AAD bearer token to be sent over plaintext HTTP. Please require both parsed.scheme == "https" and an approved Azure hostname, with a regression test that rejects an HTTP Azure-looking endpoint.
  2. Keep SKILLOPT_SLEEP_CHAT_EXTRA_BODY compat-only. The current unconditional if self.chat_extra_body also attaches it in managed-identity Azure mode, despite the new documentation and compatibility promise. Please gate it with compat mode (or otherwise make the Azure behavior explicit) and add an Azure-mode test.

These are directly within the credential-safety and backward-compatibility contract of this PR. Once they are addressed in this original PR, we can re-review quickly and preserve your authorship and contribution history.

@Yif-Yang
Yif-Yang merged commit be21846 into microsoft:main Jul 14, 2026
1 check passed
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