Skip to content

feat(ext): add route selector extension point and adaptive strategy - #611

Merged
SantiagoDePolonia merged 9 commits into
mainfrom
feat/ext-route-selector
Jul 30, 2026
Merged

feat(ext): add route selector extension point and adaptive strategy#611
SantiagoDePolonia merged 9 commits into
mainfrom
feat/ext-route-selector

Conversation

@SantiagoDePolonia

@SantiagoDePolonia SantiagoDePolonia commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds a routing extension point to the public ext API so extension builds can steer load balancing for virtual models:

  • ext.RouteSelector (ext/route.go): Select picks among currently viable targets of a load-balanced virtual model; OnAttemptStart/OnAttemptEnd observe every upstream attempt (primaries, retries, failovers) via the llmclient hooks, so selectors score targets from real traffic. Registered through a single slot on the registry (RegisterRouteSelector).
  • New adaptive load-balancing strategy for virtual models: delegates target choice to the registered selector. Candidates carry provider/model, configured weight, and registry pricing.
  • Wiring (internal/app/app.go): selector hooks attach before providers are created (same rule as the health tracker); the virtual-models service gets the selector alongside the capacity probe.

Safety / portability

  • Session affinity, rate-limit capacity filtering, failover chains, and retries all stay in core — the selector only picks the primary among viable targets.
  • Fail-open by design: no selector registered, selector declines, answers outside the pool, or panics (recovered and logged, both in selection and observation) → exact round_robin behavior. Configs using adaptive stay portable between plain core and extended builds.
  • Single-viable-target pools bypass the selector, so aliases behave identically with and without one.
  • An empty registry keeps adding zero request overhead.

Tests

  • ext: registry single-slot semantics, RouteTarget.Qualified().
  • virtualmodels: selector delegation (request shape incl. pricing), fallback matrix (no selector / decline / out-of-pool answer / panic), single-target bypass.
  • Full suite + race detector green (pre-commit make test-race).

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added adaptive virtual-model load-balancing with selector-driven target selection and fallback to weighted round-robin.
    • Enabled route-selector extensions to steer routing using session/candidate context and attempt lifecycle callbacks.
    • Updated the dashboard/editor to surface available strategy options from runtime configuration.
  • Documentation
    • Expanded config and help text to document the adaptive strategy and its “extension required, otherwise fallback” behavior.
  • Tests
    • Added coverage for selector registration behavior, adaptive delegation/fallback (including panic/decline), single-target bypass, candidate pricing copying, and route target formatting.

Extensions can now steer load balancing for virtual models. A new
ext.RouteSelector registers through the registry's single selector slot
and is consulted by redirects using the new "adaptive" strategy; it picks
among the currently viable targets (catalog-supported, with rate-limit
capacity) and observes every upstream attempt — primaries, retries, and
failovers — through the llmclient hooks, so it can score targets by real
traffic.

Session affinity, capacity filtering, failover chains, and retries all
remain core's responsibility. Without a registered selector — or when the
selector declines, answers outside the pool, or panics (contained and
logged) — the adaptive strategy behaves exactly like round_robin, so
configs stay portable between core and extended builds.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 28, 2026 17:07

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@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

Adds the adaptive virtual-model balancing strategy, a public route-selector contract, registry registration, application lifecycle hooks, selector-based resolution with round-robin fallback, dashboard exposure, and tests.

Changes

Adaptive routing

Layer / File(s) Summary
Routing contract and registry
ext/route.go, ext/registry.go, ext/ext.go, ext/registry_test.go
Defines route data and selector callbacks, then adds single-slot registry storage and registration APIs.
Adaptive strategy and fallback
internal/virtualmodels/*, config/..., internal/admin/handler_virtualmodels.go
Accepts adaptive, delegates target selection to a registered selector, and falls back to weighted round robin when needed.
Application hook integration
internal/app/app.go
Installs selector attempt hooks and connects the selector to the virtual-model service during startup.
Dashboard strategy availability
internal/admin/handler.go, internal/app/app.go, web/dashboard/...
Publishes available strategies and renders dynamic virtual-model strategy options.
Adaptive routing validation
internal/virtualmodels/adaptive_test.go, internal/app/app_test.go, web/dashboard/tests/...
Tests routing delegation, metadata copying, fallback behavior, dashboard configuration, and strategy option formatting.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant ExtensionRegistry
  participant App
  participant ProviderFactory
  participant VirtualModelService
  participant RouteSelector
  participant Dashboard
  ExtensionRegistry->>App: expose registered selector
  App->>ProviderFactory: install attempt hooks
  App->>VirtualModelService: install selector
  VirtualModelService->>RouteSelector: select from RouteRequest
  ProviderFactory->>RouteSelector: report attempt lifecycle
  App->>Dashboard: publish supported strategies
  Dashboard->>App: load runtime strategy configuration
Loading

Possibly related PRs

Suggested reviewers: copilot

Poem

I’m a rabbit routing through the model meadow,
Choosing bright paths where the tokens flow.
If the selector naps, round-robin takes flight,
Hooks share attempts from morning to night.
Adaptive carrots now grow in the code—
Hop, test, and ship down the balanced road!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding a route selector extension point and adaptive strategy.
Description check ✅ Passed The PR includes the changed behavior, safety notes, and tests, but should follow the template's 'Description' heading more closely.
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.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/ext-route-selector

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codecov-commenter

codecov-commenter commented Jul 28, 2026

Copy link
Copy Markdown

⚠️ Please install the 'codecov app svg image' to ensure uploads and comments are reliably processed by Codecov.

Codecov Report

❌ Patch coverage is 65.92593% with 46 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
internal/app/app.go 35.00% 36 Missing and 3 partials ⚠️
internal/virtualmodels/service.go 66.66% 2 Missing and 2 partials ⚠️
internal/virtualmodels/adaptive.go 93.75% 1 Missing and 1 partial ⚠️
ext/registry.go 88.88% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@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: 6

🤖 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 `@config/config.example.yaml`:
- Line 64: Update the strategy comment near the strategy configuration example
to describe the routing extension as optional rather than required, while
preserving that adaptive is valid without a selector and falls back to
round_robin.

In `@ext/registry_test.go`:
- Around line 88-102: Convert TestRegistryRouteSelectorSingleSlot and
TestRouteTargetQualified into table-driven tests covering unset, replacement,
and nil-reset selector behavior plus route-target qualification. Reuse each
case’s inputs and expected outputs through subtests, preserving the current
assertions and behavior.

In `@internal/app/app.go`:
- Around line 117-127: Update the recovery handler inside routeSelectorHooks so
it performs no extension calls, including selector.Name(), and logs only fixed,
non-sensitive metadata such as the observation event. Remove the recovered panic
value from slog.Error while preserving panic containment and the existing error
message.

In `@internal/virtualmodels/adaptive_test.go`:
- Around line 82-88: Expand the request-translation assertions in the relevant
test to compare the complete req.Candidates slice against expected
ext.RouteCandidate metadata, including Weight, OutputPerMtok, InputPerMtok,
provider/model fields, and nil versus populated optional prices. Convert the
coverage to table-driven tests so multiple candidate and parameter-mapping cases
are validated, while preserving the existing request translation behavior.

In `@internal/virtualmodels/adaptive.go`:
- Around line 20-25: Update the deferred recovery handler around Select so panic
reporting does not call the extension-provided selector.Name(); use a constant
label or panic-safe helper while preserving the resolvedTarget{} false fallback.
Add a regression test covering both Select and Name panicking and verify
round-robin fallback is returned without another panic.
- Around line 22-23: Update the panic recovery logging around the route selector
fallback to stop including the raw recovered value r. Remove the panic field or
replace it with a non-sensitive panic classification, while preserving the
selector, source, and fallback behavior.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: fbb3af64-6418-4421-a897-87bf4dde574b

📥 Commits

Reviewing files that changed from the base of the PR and between 20aa6c5 and c31d624.

📒 Files selected for processing (14)
  • config/config.example.yaml
  • config/virtualmodels.go
  • ext/ext.go
  • ext/registry.go
  • ext/registry_test.go
  • ext/route.go
  • internal/admin/handler_virtualmodels.go
  • internal/app/app.go
  • internal/virtualmodels/adaptive.go
  • internal/virtualmodels/adaptive_test.go
  • internal/virtualmodels/balancer.go
  • internal/virtualmodels/service.go
  • internal/virtualmodels/types.go
  • internal/virtualmodels/validation.go

Comment thread config/config.example.yaml Outdated
Comment thread ext/registry_test.go
Comment thread internal/app/app.go
Comment thread internal/virtualmodels/adaptive_test.go Outdated
Comment thread internal/virtualmodels/adaptive.go
Comment thread internal/virtualmodels/adaptive.go Outdated
Comment thread internal/virtualmodels/adaptive.go Outdated
Comment thread internal/app/app.go
Comment thread internal/virtualmodels/adaptive.go Outdated
@greptile-apps

greptile-apps Bot commented Jul 28, 2026

Copy link
Copy Markdown

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains.

T-Rex T-Rex Logs

What T-Rex did

  • Posted a finding-comment proof for P1, confirming the issue related to runtime config behavior.
  • Validated pre-change and post-change runtime config behavior: after starting the app with proofSelector registered, GET /admin/runtime/config still omits VIRTUAL_MODEL_STRATEGIES, so the adaptive help copy remains absent.
  • Identified the root cause in internal/admin/handler.go: normalizeDashboardRuntimeConfig reconstructs DashboardConfigResponse without copying VirtualModelStrategies, discarding the value generated earlier.
  • Collected and linked artifacts (videos, images, and logs) that show the baseline and post-change states and document the missing config path for reviewer inspection.

View all artifacts

T-Rex Ran code and verified through T-Rex

Sequence Diagram

sequenceDiagram
  participant Client
  participant VM as Virtual Model Service
  participant Selector as Route Selector
  participant Provider
  Client->>VM: Request virtual model
  VM->>VM: Apply session affinity and capacity filtering
  alt Multiple viable targets and adaptive selector installed
    VM->>Selector: Select(viable candidates)
    alt Valid candidate selected
      Selector-->>VM: Qualified target
    else Decline, invalid result, or panic
      VM->>VM: Weighted round-robin fallback
    end
  else No selector or single viable target
    VM->>VM: Core target selection
  end
  VM->>Provider: Upstream call
  VM->>Selector: OnAttemptStart(target)
  Provider-->>VM: Final outcome after transport retries
  VM->>Selector: OnAttemptEnd(aggregated outcome)
  VM-->>Client: Response
Loading

Comments Outside Diff (1)

  1. General comment

    P1 Runtime-config normalization discards VIRTUAL_MODEL_STRATEGIES

    • Bug
      • A real application run with a registered route-selector extension returns HTTP 200 from /admin/runtime/config, but the JSON omits VIRTUAL_MODEL_STRATEGIES. The virtual-model editor therefore falls back to round_robin,cost; Adaptive and its conditional explanatory copy are unreachable through the advertised production flow.
    • Cause
      • normalizeDashboardRuntimeConfig in internal/admin/handler.go creates a new DashboardConfigResponse but does not assign VirtualModelStrategies. WithDashboardRuntimeConfig passes the generated configuration through this function, so the strategy list is erased before DashboardConfig serializes it.
    • Fix
      • Copy and trim the new field in normalizeDashboardRuntimeConfig, for example VirtualModelStrategies: strings.TrimSpace(values.VirtualModelStrategies). Add a handler/API contract test that constructs the handler with VIRTUAL_MODEL_STRATEGIES=round_robin,cost,adaptive and asserts the live /admin/runtime/config response preserves it.

    T-Rex Ran code and verified through T-Rex

Reviews (2): Last reviewed commit: "fix(dashboard): describe adaptive as ext..." | Re-trigger Greptile

Panic recovery around selector calls no longer re-enters extension code:
the selector's name is captured panic-safe at install time, so a Name
that panics mid-recovery can no longer escape the handler and abort the
request instead of falling back. The recovered value is no longer
logged — it is extension-controlled and could carry request data.

Candidate pricing is now defensively copied: selectors received the
catalog's own *float64 values, so a misbehaving extension could mutate
the prices that cost routing and cost calculation later read.

The per-attempt observation contract is corrected to match behavior:
hooks fire once per upstream call, and transport-level retries inside
the provider client are aggregated into that call's single outcome
(final status, duration spanning retry backoff). Moving observation
inside the client retry loop would change hook semantics for every
consumer (metrics, health tracking) and is out of scope here.

Also: registry selector-slot tests are table-driven (incl. nil reset),
the delegation test asserts the full candidate set, a regression test
covers the double-panic path, and the example config no longer implies
the adaptive strategy requires an extension.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 28, 2026 17:39

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Addressed the review findings in 189beca:

  • Recovery re-panic (P1): the selector's name is now captured panic-safe at install time (selectorLabel, both in virtualmodels and app); recovery handlers log only fixed metadata and never call back into extension code. The raw panic value is no longer logged (extension-controlled, could carry request data). Regression test added for the Select-and-Name-both-panic path.
  • Per-attempt contract (P1): fixed the contract, not the plumbing — ext/route.go now documents that hooks fire once per upstream call, with transport-level retries inside the provider client aggregated into that call's outcome (final status; duration spans retry backoff, so retry-heavy targets still score slower). Moving observation inside the client retry loop would change llmclient.Hooks semantics for every existing consumer (Prometheus metrics, health tracker) and belongs in its own PR if we ever want per-transport-attempt observability.
  • Pricing escape (P2): candidates now carry defensive copies of the catalog's per-Mtok prices; test asserts a selector writing through the pointers cannot change what cost routing later reads.
  • CodeRabbit: example-config wording fixed (adaptive is optional, falls back to round_robin), registry selector-slot tests are table-driven (unset/single/replace/nil-reset), and the delegation test asserts the complete candidate set.

#612 has been rebased on top.

@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 `@internal/virtualmodels/adaptive_test.go`:
- Around line 119-135: Expand TestBalancer_AdaptiveCandidatePricingIsCopied into
a table-driven isolation test that mutates both InputPerMtok and OutputPerMtok
for every selector candidate, then verifies the corresponding pricing pointers
for every catalog model remain unchanged. Use the existing candidate and catalog
model symbols to cover all candidates and both pricing fields, while preserving
the current defensive-copy assertion behavior.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 10507680-ad9f-47ea-a5ff-fc0f9baa0dc0

📥 Commits

Reviewing files that changed from the base of the PR and between c31d624 and 189beca.

📒 Files selected for processing (7)
  • config/config.example.yaml
  • ext/registry_test.go
  • ext/route.go
  • internal/app/app.go
  • internal/virtualmodels/adaptive.go
  • internal/virtualmodels/adaptive_test.go
  • internal/virtualmodels/service.go

Comment thread internal/virtualmodels/adaptive_test.go
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 28, 2026 17:49

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Follow-up from the second review pass in b3c07a4: the pricing-isolation test now mutates every pricing pointer of every candidate and verifies all catalog prices stay intact.

The strategy dropdown was hardcoded to round_robin and cost, so the new
adaptive strategy was unreachable from the UI even on deployments with a
route selector registered — and hardcoding would have offered it on
plain core, where it silently falls back to round robin.

/admin/runtime/config now carries VIRTUAL_MODEL_STRATEGIES, the comma-
separated strategies this deployment supports; adaptive appears only
when a route-selector extension is registered. The backend owns the
values, the dashboard owns the labels (unknown values render as their
raw value), and the editor keeps the edited row's current strategy
selectable even when the deployment no longer offers it, so opening an
adaptive virtual model on a plain-core dashboard no longer renders a
blank select that could silently rewrite the strategy on save.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 29, 2026 09:50

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Added in 454b7cc (discussed with the team): the strategy dropdown is now server-driven. /admin/runtime/config carries a new VIRTUAL_MODEL_STRATEGIES key (comma-separated); adaptive is listed only when a route-selector extension is registered, so plain-core dashboards never offer a strategy that would silently fall back to round robin, while extended builds get it configurable from the UI. Values come from the backend, labels stay in the frontend (unknown values render raw for forward-compat), and the editor keeps an edited row's current strategy selectable even when the deployment doesn't offer it — fixing the pre-existing blank-select trap when opening an API-created adaptive VM on plain core. Covered by the existing runtime-config contract test plus new Go and dashboard unit tests; dist rebuilt.

@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 `@web/dashboard/src/pages/models/virtualModelsLogic.js`:
- Around line 171-175: Update the adaptive label in STRATEGY_OPTION_LABELS at
web/dashboard/src/pages/models/virtualModelsLogic.js lines 171-175 to describe
target selection as delegated to the configured route-selector extension,
without promising health, latency, or cost inputs. Apply the same generic
extension-defined wording in
web/dashboard/src/pages/models/VirtualModelEditor.svelte lines 47-49.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4cb4e178-95eb-4e78-8333-da9006334974

📥 Commits

Reviewing files that changed from the base of the PR and between 189beca and 454b7cc.

⛔ Files ignored due to path filters (3)
  • internal/admin/dashboard/static/dist/assets/index-BOEWOpVo.js is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/assets/index-jnxLFx0i.js is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/index.html is excluded by !**/dist/**
📒 Files selected for processing (9)
  • internal/admin/handler.go
  • internal/app/app.go
  • internal/app/app_test.go
  • internal/virtualmodels/adaptive_test.go
  • web/dashboard/src/lib/stores/runtimeConfig.svelte.js
  • web/dashboard/src/pages/models/VirtualModelEditor.svelte
  • web/dashboard/src/pages/models/virtualModels.svelte.js
  • web/dashboard/src/pages/models/virtualModelsLogic.js
  • web/dashboard/tests/models-virtual-models.test.js

Comment thread web/dashboard/src/pages/models/virtualModelsLogic.js
The label promised health/latency/cost routing, but core's contract only
delegates target choice to the registered extension — describe that,
not one extension's policy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 29, 2026 15:32

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

Addressed in fe6a0e6: the adaptive label and help text now describe the contract ("target chosen by the registered routing extension") rather than one extension's policy.

# Conflicts:
#	internal/admin/dashboard/static/dist/index.html
#	web/dashboard/src/pages/models/VirtualModelEditor.svelte
Copilot AI review requested due to automatic review settings July 30, 2026 15:11

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@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 `@web/dashboard/src/pages/models/VirtualModelEditor.svelte`:
- Around line 50-52: Update the adaptive help-text condition in
VirtualModelEditor to check the server-provided supported-strategy list for
adaptive support instead of vm.vmStrategyOptions(). Preserve the existing
explanatory text and rendering behavior, including compatibility with edited
unsupported strategy values.
🪄 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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 4bd5d9c5-0785-4ff4-8f66-1826b4a6e263

📥 Commits

Reviewing files that changed from the base of the PR and between fe6a0e6 and 38263ff.

⛔ Files ignored due to path filters (2)
  • internal/admin/dashboard/static/dist/assets/index-CXC5vqx6.js is excluded by !**/dist/**
  • internal/admin/dashboard/static/dist/index.html is excluded by !**/dist/**
📒 Files selected for processing (1)
  • web/dashboard/src/pages/models/VirtualModelEditor.svelte

Comment thread web/dashboard/src/pages/models/VirtualModelEditor.svelte Outdated
The help condition used the dropdown options, which include an edited
row's unsupported value for compatibility — so an adaptive virtual model
opened on a deployment without a route selector still showed help
claiming a registered extension picks targets. Gate on the
server-provided strategy list instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 30, 2026 15:44

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia

Copy link
Copy Markdown
Contributor Author

CodeRabbit's help-text finding fixed in 094d1d1: the adaptive help sentence now gates on the server-provided strategy list (runtimeConfig.virtualModelStrategies()) instead of the dropdown options, which include an edited row's unsupported value for compatibility — so an adaptive VM opened on plain core no longer shows help claiming an extension picks targets. #612 merged forward.

# Conflicts:
#	internal/admin/dashboard/static/dist/index.html
Copilot AI review requested due to automatic review settings July 30, 2026 15:54

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

…normalization

normalizeDashboardRuntimeConfig rebuilt the response field-by-field and
dropped VirtualModelStrategies, so /admin/runtime/config never exposed
the strategy list and the dashboard could not offer adaptive. Carry the
field through and assert it in the handler-level runtime-config test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 30, 2026 16:03

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@SantiagoDePolonia
SantiagoDePolonia merged commit 5f497a6 into main Jul 30, 2026
18 checks 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.

3 participants