Skip to content

fix(models): model deployment wait for IGW ready - #940

Merged
ironcommit merged 1 commit into
mainfrom
agent-k8s-igw-virtual-model-race/rsadler
Jul 30, 2026
Merged

fix(models): model deployment wait for IGW ready#940
ironcommit merged 1 commit into
mainfrom
agent-k8s-igw-virtual-model-race/rsadler

Conversation

@ironcommit

@ironcommit ironcommit commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Added synchronous and asynchronous helpers that wait for an OpenAI model to become available.
    • Supports workspace-scoped and qualified model names.
    • Provides configurable polling intervals and timeouts with clear timeout details.
  • Bug Fixes

    • Deployment invocation now waits for the model to be ready, reducing failures caused by readiness delays.

@ironcommit
ironcommit requested review from a team as code owners July 28, 2026 03:19
@ironcommit
ironcommit requested a review from benmccown July 28, 2026 03:19
@github-actions github-actions Bot added the fix label Jul 28, 2026
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The models client now waits for OpenAI gateway model readiness through synchronous and asynchronous polling. Container-agent deployment invokes the agent only after the expected model is available.

Changes

IGW model readiness

Layer / File(s) Summary
Readiness polling and validation
packages/models/src/models/resources.py, packages/models/tests/test_client.py
Adds workspace-aware route normalization, synchronous and asynchronous polling, mismatch and 404 handling, timeout-aware sleeping, and coverage for retry, timeout, and validation behavior.
Container invocation integration
e2e/agents_deploy_helpers.py
Waits for the deployed OpenAI model before invoking the container-mode agent.

Sequence Diagram(s)

sequenceDiagram
  participant DeploymentHelper
  participant ModelsResource
  participant OpenAIGatewayModels
  participant AgentsGateway
  DeploymentHelper->>ModelsResource: wait_for_openai_model(model_name, workspace)
  ModelsResource->>OpenAIGatewayModels: poll models.get(route_name)
  OpenAIGatewayModels-->>ModelsResource: model response or NotFoundError
  ModelsResource-->>DeploymentHelper: ready model or TimeoutError
  DeploymentHelper->>AgentsGateway: invoke agent
Loading

Suggested reviewers: benmccown, tylersbray, mikeknep

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 80.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title matches the main fix: waiting for the deployed model/gateway to be ready before invocation.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent-k8s-igw-virtual-model-race/rsadler

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/core/models/src/nmp/core/models/controllers/provider_reconciler.py`:
- Around line 1048-1055: Update the autoprovisioned VirtualModel deletion flow
around _virtual_model_changed_after_snapshot and delete() to pass the resource
version, etag, or equivalent version captured during listing as a server-side
delete precondition. Preserve the existing snapshot check, but ensure delete is
rejected when the VirtualModel changes between listing and deletion.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: c0ac6f28-197c-497a-b5de-e4c71bed233b

📥 Commits

Reviewing files that changed from the base of the PR and between ecf5177 and 36d52c9.

📒 Files selected for processing (6)
  • e2e/agents_deploy_helpers.py
  • packages/nmp_testing/src/nmp/testing/__init__.py
  • packages/nmp_testing/src/nmp/testing/utils.py
  • packages/nmp_testing/tests/unit/test_utils.py
  • services/core/models/src/nmp/core/models/controllers/provider_reconciler.py
  • services/core/models/tests/unit/controllers/test_provider_reconciler.py

Comment thread services/core/models/src/nmp/core/models/controllers/provider_reconciler.py Outdated
@github-actions

github-actions Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor
Suite Lines Covered Line Rate Branch Rate
Unit Tests 28176/36009 78.2% 62.7%
Integration Tests 16754/34727 48.2% 20.8%

@ironcommit
ironcommit force-pushed the agent-k8s-igw-virtual-model-race/rsadler branch from 36d52c9 to b7c37ca Compare July 28, 2026 16:40

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/models/src/models/resources.py`:
- Around line 322-330: Bound the retry delays by the remaining timeout in both
polling methods: update the synchronous loop at
packages/models/src/models/resources.py#L322-L330 to sleep for the smaller of
poll_interval and the remaining timeout, and apply the equivalent min-bound to
asyncio.sleep at packages/models/src/models/resources.py#L764-L772. Add a test
using a nonzero poll interval that verifies neither method waits beyond its
configured timeout.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 07547025-32fc-4059-b61d-a8d91d810313

📥 Commits

Reviewing files that changed from the base of the PR and between 36d52c9 and b7c37ca.

⛔ Files ignored due to path filters (1)
  • sdk/python/nemo-platform/src/nemo_platform/models/resources.py is excluded by !sdk/**
📒 Files selected for processing (5)
  • e2e/agents_deploy_helpers.py
  • packages/models/src/models/resources.py
  • packages/models/tests/test_client.py
  • services/core/models/src/nmp/core/models/controllers/provider_reconciler.py
  • services/core/models/tests/unit/controllers/test_provider_reconciler.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • services/core/models/tests/unit/controllers/test_provider_reconciler.py

Comment thread packages/models/src/models/resources.py Outdated
@ironcommit
ironcommit force-pushed the agent-k8s-igw-virtual-model-race/rsadler branch from b7c37ca to 23ec486 Compare July 28, 2026 17:06

@coderabbitai coderabbitai Bot 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@services/core/models/tests/unit/controllers/test_provider_reconciler.py`:
- Around line 1912-1926: Update the VirtualModel test helper and its callers to
distinguish an omitted updated_at from an explicit None using an unset sentinel,
while preserving the updated_at or created_at or now precedence. Expand the
relevant tests around the reconciler cases to cover created_at < snapshot <
updated_at and explicit updated_at=None with created_at both before and after
the snapshot, ensuring regressions in updated_at precedence or fallback are
detected.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f67a1c41-e15f-4c22-9318-9d682341482b

📥 Commits

Reviewing files that changed from the base of the PR and between b7c37ca and 23ec486.

⛔ Files ignored due to path filters (1)
  • sdk/python/nemo-platform/src/nemo_platform/models/resources.py is excluded by !sdk/**
📒 Files selected for processing (5)
  • e2e/agents_deploy_helpers.py
  • packages/models/src/models/resources.py
  • packages/models/tests/test_client.py
  • services/core/models/src/nmp/core/models/controllers/provider_reconciler.py
  • services/core/models/tests/unit/controllers/test_provider_reconciler.py
🚧 Files skipped from review as they are similar to previous changes (4)
  • e2e/agents_deploy_helpers.py
  • packages/models/tests/test_client.py
  • services/core/models/src/nmp/core/models/controllers/provider_reconciler.py
  • packages/models/src/models/resources.py

Comment thread services/core/models/tests/unit/controllers/test_provider_reconciler.py Outdated

@benmccown benmccown 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.

LGTM!

@ironcommit
ironcommit force-pushed the agent-k8s-igw-virtual-model-race/rsadler branch from 23ec486 to 47b1040 Compare July 29, 2026 22:44

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
packages/models/src/models/resources.py (1)

57-84: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Poll loops only tolerate NotFoundError/id-mismatch, unlike wait_for_gateway.

_poll_until_ready/_async_poll_until_ready catch only _PollPending and NotFoundError; any other exception (e.g. a transient APIStatusError such as a 503 during gateway warm-up, once SDK auto-retries are exhausted) aborts the poll immediately instead of retrying for the remaining timeout. wait_for_gateway in this same file deliberately catches broad Exception for this exact "gateway isn't ready yet" scenario. Given this PR's goal is to close a deployment race condition, a stray transient error here would just reintroduce flakiness at the model-readiness step instead of the provider-readiness step.

nemo_platform's SDK auto-retries connection errors/408/409/429/5xx twice by default, so this is a residual-risk gap rather than a guaranteed failure.

♻️ Broaden retry tolerance to match `wait_for_gateway`
     while time.time() - start_time < timeout:
         try:
             return attempt()
         except _PollPending as exc:
             last_error = exc.reason
-        except NotFoundError as exc:
+        except (NotFoundError, APIStatusError, APIConnectionError) as exc:
             last_error = exc

Apply the same change in _async_poll_until_ready. Confirm APIStatusError/APIConnectionError are the correct base classes exported from nemo_platform for this SDK version.

Also applies to: 97-114

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/models/src/models/resources.py` around lines 57 - 84, Broaden
exception handling in both _poll_until_ready and _async_poll_until_ready to
retry transient gateway-readiness failures, including the appropriate
nemo_platform API status and connection error base classes, instead of aborting
immediately. Match wait_for_gateway’s established broad retry behavior while
preserving _PollPending/NotFoundError handling, timeout tracking, and final
timeout_message construction; verify the imported exception classes are
supported by this SDK version.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/models/src/models/resources.py`:
- Around line 57-84: Broaden exception handling in both _poll_until_ready and
_async_poll_until_ready to retry transient gateway-readiness failures, including
the appropriate nemo_platform API status and connection error base classes,
instead of aborting immediately. Match wait_for_gateway’s established broad
retry behavior while preserving _PollPending/NotFoundError handling, timeout
tracking, and final timeout_message construction; verify the imported exception
classes are supported by this SDK version.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 70057f11-5b68-49cd-a344-ba40c5e40454

📥 Commits

Reviewing files that changed from the base of the PR and between 23ec486 and 47b1040.

⛔ Files ignored due to path filters (1)
  • sdk/python/nemo-platform/src/nemo_platform/models/resources.py is excluded by !sdk/**
📒 Files selected for processing (3)
  • e2e/agents_deploy_helpers.py
  • packages/models/src/models/resources.py
  • packages/models/tests/test_client.py

@ironcommit
ironcommit force-pushed the agent-k8s-igw-virtual-model-race/rsadler branch from 47b1040 to d6c44a7 Compare July 29, 2026 23:09

@coderabbitai coderabbitai Bot 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.

🧹 Nitpick comments (1)
packages/models/tests/test_client.py (1)

511-546: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Async coverage lags sync. No async test for mismatched id (the _PollPending path) or workspace-qualified names. Cheap to mirror test_wait_for_openai_model_retries_unexpected_model_id with an AsyncMock.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/models/tests/test_client.py` around lines 511 - 546, Extend the
async wait_for_openai_model tests with AsyncMock coverage for the _PollPending
path when the returned model id does not match, mirroring
test_wait_for_openai_model_retries_unexpected_model_id. Also add an async case
using a workspace-qualified model name, verifying the expected workspace/name
arguments and retry behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@packages/models/tests/test_client.py`:
- Around line 511-546: Extend the async wait_for_openai_model tests with
AsyncMock coverage for the _PollPending path when the returned model id does not
match, mirroring test_wait_for_openai_model_retries_unexpected_model_id. Also
add an async case using a workspace-qualified model name, verifying the expected
workspace/name arguments and retry behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: f91c640e-696f-47f2-bd0a-2b60a6741f47

📥 Commits

Reviewing files that changed from the base of the PR and between 47b1040 and d6c44a7.

⛔ Files ignored due to path filters (1)
  • sdk/python/nemo-platform/src/nemo_platform/models/resources.py is excluded by !sdk/**
📒 Files selected for processing (3)
  • e2e/agents_deploy_helpers.py
  • packages/models/src/models/resources.py
  • packages/models/tests/test_client.py

@ironcommit ironcommit changed the title fix(models): model deployment race condition fix(models): model deployment wait for IGW ready Jul 30, 2026
Signed-off-by: Ryan S <267728323+ironcommit@users.noreply.github.com>
@ironcommit
ironcommit force-pushed the agent-k8s-igw-virtual-model-race/rsadler branch from d6c44a7 to a6bd306 Compare July 30, 2026 17:13
@ironcommit
ironcommit enabled auto-merge July 30, 2026 17:15
@ironcommit
ironcommit added this pull request to the merge queue Jul 30, 2026
Merged via the queue into main with commit 5fe01ba Jul 30, 2026
57 checks passed
@ironcommit
ironcommit deleted the agent-k8s-igw-virtual-model-race/rsadler branch July 30, 2026 17:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants