Skip to content

refactor(core): streamline model selector resolution#177

Merged
SantiagoDePolonia merged 5 commits intomainfrom
refactor/model-selector-resolution-flow
Mar 26, 2026
Merged

refactor(core): streamline model selector resolution#177
SantiagoDePolonia merged 5 commits intomainfrom
refactor/model-selector-resolution-flow

Conversation

@SantiagoDePolonia
Copy link
Copy Markdown
Contributor

@SantiagoDePolonia SantiagoDePolonia commented Mar 25, 2026

Summary

  • preserve requested selector provenance with an explicit requested-selector type instead of loose model/provider strings
  • make alias resolution and batch planning consume that typed selector so explicit provider hints and prefixed model syntax are not conflated
  • disable translated alias rewriting by default in the alias provider wrapper so explicit server-side planning remains the primary execution path
  • clarify in code and comments that request provider is a gateway routing hint that is stripped before upstream execution

Testing

  • go test ./internal/core ./internal/server ./internal/aliases ./internal/auditlog ./internal/providers

Summary by CodeRabbit

  • Refactor

    • Unified request selector flow for model resolution, producing more consistent normalization, per-item batch validation with indexed errors, and updated default behavior that skips translated-route rewriting unless enabled.
  • Documentation

    • Clarified Provider fields are gateway routing hints and are cleared before upstream execution.
  • Tests

    • Updated tests to align with the new selector-based request shape and default provider-handling behavior.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Mar 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 75f28453-26c4-4f07-9e2f-e99185a9d950

📥 Commits

Reviewing files that changed from the base of the PR and between 6e2cf91 and c0c52ae.

📒 Files selected for processing (1)
  • internal/aliases/service.go

📝 Walkthrough

Walkthrough

Centralize raw request inputs into a new core.RequestedModelSelector, update alias/service/provider resolution APIs and call sites to accept and normalize that selector, and propagate the selector-based flow through server, batch, router, and tests.

Changes

Cohort / File(s) Summary
Core requested selector type
internal/core/requested_model_selector.go
Add RequestedModelSelector type, constructor, Normalize() and RequestedQualifiedModel() helpers to capture raw request model/provider inputs.
Aliases: provider & preparer
internal/aliases/provider.go, internal/aliases/batch_preparer.go, internal/aliases/service.go
Switch alias resolution helpers and Provider/Service ResolveModel to accept RequestedModelSelector; adjust resolution control flow, remove ResolveSelector, and change NewProvider default options.
Server resolver & audit/plan flows
internal/server/request_model_resolution.go, internal/server/execution_plan_helpers_test.go
Update RequestModelResolver interface and resolution callers to pass RequestedModelSelector; populate plans/audit entries with the new Requested field.
Batch & native batch support
internal/server/native_batch_support.go, internal/core/batch_semantic.go
Decode per-item requested selectors, normalize before resolution, and use resolver.ResolveModel(requested) for provider-type checks and batch validation.
Core request resolution shape
internal/core/request_model_resolution.go, internal/core/request_model_resolution_test.go
Replace raw RequestedModel/RequestedProvider fields with Requested RequestedModelSelector; update RequestedQualifiedModel logic and tests.
Responses/types comments
internal/core/responses.go, internal/core/types.go
Clarify Provider field is a gateway routing hint (comment only).
Router parameter rename
internal/providers/router.go
Rename providerproviderHint in routing helpers and ensure Provider is cleared before upstream dispatch.
Tests & providers
internal/aliases/provider_test.go, internal/server/handlers_test.go, internal/auditlog/auditlog_test.go, internal/server/model_validation_test.go
Update tests to construct RequestedModelSelector, adjust assertions to the new Requested shape, add/adjust provider constructor usage for options.

Sequence Diagram(s)

sequenceDiagram
    participant Client as Client
    participant Router as Router
    participant Resolver as RequestModelResolver
    participant AliasSvc as AliasService
    participant Upstream as UpstreamProvider

    Client->>Router: HTTP request with model + providerHint
    Router->>Router: build RequestedModelSelector(model, providerHint)
    Router->>Resolver: ResolveModel(requested)
    alt Resolver delegates to alias service
        Resolver->>AliasSvc: resolveRequested(requested)
        AliasSvc-->>Resolver: (resolvedSelector, changed, err)
        Resolver-->>Router: (resolvedSelector, changed, err)
    else Resolver absent or no alias
        Resolver-->>Router: (requested.Normalize(), false, nil)
    end
    Router->>Upstream: forward request with resolved selector (Provider cleared / normalized)
    Upstream-->>Router: response
    Router-->>Client: response
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Suggested labels

release:internal

Poem

🐰 A hop, a nibble, selectors neat—

one typed hint makes resolution sweet.
From request to service, tidy and true,
normalize, resolve, then forward through.
Hippity-hop—routing refreshed for you! 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'refactor(core): streamline model selector resolution' accurately describes the main change of the PR: introducing a typed RequestedModelSelector to replace loose model/provider strings and simplifying the model selector resolution flow.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 refactor/model-selector-resolution-flow

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 and usage tips.

@SantiagoDePolonia SantiagoDePolonia force-pushed the refactor/model-selector-resolution-flow branch from dc7b708 to d4f9431 Compare March 25, 2026 22:54
@SantiagoDePolonia SantiagoDePolonia changed the base branch from fix/aliases-conflicts-error to main March 25, 2026 22:54
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/aliases/batch_preparer.go`:
- Around line 62-72: resolveAliasRequestSelector redundantly reconstructs the
RequestedModelSelector with core.NewRequestedModelSelector even though
resolveAliasModel already performs that reconstruction; remove the duplicate
core.NewRequestedModelSelector(requested.Model, requested.ProviderHint) from
resolveAliasRequestSelector and pass the original requested (or its normalized
form) into resolveAliasModel, then return either the selector (if changed) or
requested.Normalize(); update usages of resolveAliasRequestSelector only if they
relied on the double reconstruction. Ensure references: function
resolveAliasRequestSelector, resolveAliasModel, core.NewRequestedModelSelector,
RequestedModelSelector, and requested.Normalize() are adjusted accordingly.
- Around line 53-60: The function resolveAliasModel redundantly reconstructs the
selector by calling core.NewRequestedModelSelector on an argument that callers
already create; remove the reassignment "requested =
core.NewRequestedModelSelector(...)" from resolveAliasModel and let the function
use the provided core.RequestedModelSelector directly (keep the Normalize call
when service==nil). If you prefer a defensive boundary instead, replace the
reconstruction with a short comment documenting that callers must pass a
properly constructed core.RequestedModelSelector; update resolveAliasModel's
docstring accordingly.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: b3846fd0-85bf-40ad-b6df-84528eaee3b3

📥 Commits

Reviewing files that changed from the base of the PR and between 6dd2b22 and dc7b708.

📒 Files selected for processing (17)
  • internal/aliases/batch_preparer.go
  • internal/aliases/provider.go
  • internal/aliases/provider_test.go
  • internal/aliases/service.go
  • internal/auditlog/auditlog_test.go
  • internal/core/batch_semantic.go
  • internal/core/request_model_resolution.go
  • internal/core/request_model_resolution_test.go
  • internal/core/requested_model_selector.go
  • internal/core/responses.go
  • internal/core/types.go
  • internal/providers/router.go
  • internal/server/execution_plan_helpers_test.go
  • internal/server/handlers_test.go
  • internal/server/model_validation_test.go
  • internal/server/native_batch_support.go
  • internal/server/request_model_resolution.go

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/aliases/service.go`:
- Line 125: The code re-normalizes the requested selector by calling
NewRequestedModelSelector on the local variable requested even though callers
(Resolve and resolveRequestModel) already construct a normalized
RequestedModelSelector; remove the redundant call to NewRequestedModelSelector
at the top of the method (where requested =
core.NewRequestedModelSelector(requested.Model, requested.ProviderHint) appears)
so the method trusts its caller-provided RequestedModelSelector, or if you
intend idempotency, document that NewRequestedModelSelector is safe to call
multiple times in the function comment for ResolveModel/Resolve; reference the
requested variable and NewRequestedModelSelector and update
Resolve()/resolveRequestModel() callers or add inline doc accordingly.

In `@internal/server/handlers_test.go`:
- Line 1217: The test currently calls aliases.NewProviderWithOptions(inner,
service, aliases.Options{}) with an empty options struct; replace
aliases.Options{} with an explicit struct literal that lists each option field
and its intended value (matching the default behavior used in this test) so the
intent is self-documenting—update the call to
aliases.NewProviderWithOptions(inner, service,
aliases.Options{<EachOptionField>: <value>, ...}) to show the chosen flags.
🪄 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

Run ID: 2960d202-9870-4cbc-bbb3-992cdb3dae8b

📥 Commits

Reviewing files that changed from the base of the PR and between dc7b708 and 6e2cf91.

📒 Files selected for processing (17)
  • internal/aliases/batch_preparer.go
  • internal/aliases/provider.go
  • internal/aliases/provider_test.go
  • internal/aliases/service.go
  • internal/auditlog/auditlog_test.go
  • internal/core/batch_semantic.go
  • internal/core/request_model_resolution.go
  • internal/core/request_model_resolution_test.go
  • internal/core/requested_model_selector.go
  • internal/core/responses.go
  • internal/core/types.go
  • internal/providers/router.go
  • internal/server/execution_plan_helpers_test.go
  • internal/server/handlers_test.go
  • internal/server/model_validation_test.go
  • internal/server/native_batch_support.go
  • internal/server/request_model_resolution.go

}

provider := aliases.NewProvider(inner, service)
provider := aliases.NewProviderWithOptions(inner, service, aliases.Options{})
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 | 🔵 Trivial

Make alias-provider options explicit in this test for intent clarity.

Using aliases.Options{} works, but explicit flags make this scenario self-documenting and less ambiguous for future readers.

♻️ Optional clarity diff
-provider := aliases.NewProviderWithOptions(inner, service, aliases.Options{})
+provider := aliases.NewProviderWithOptions(inner, service, aliases.Options{
+	DisableTranslatedRequestProcessing: false,
+	DisableNativeBatchPreparation:      false,
+})
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
provider := aliases.NewProviderWithOptions(inner, service, aliases.Options{})
provider := aliases.NewProviderWithOptions(inner, service, aliases.Options{
DisableTranslatedRequestProcessing: false,
DisableNativeBatchPreparation: false,
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/server/handlers_test.go` at line 1217, The test currently calls
aliases.NewProviderWithOptions(inner, service, aliases.Options{}) with an empty
options struct; replace aliases.Options{} with an explicit struct literal that
lists each option field and its intended value (matching the default behavior
used in this test) so the intent is self-documenting—update the call to
aliases.NewProviderWithOptions(inner, service,
aliases.Options{<EachOptionField>: <value>, ...}) to show the chosen flags.

@SantiagoDePolonia SantiagoDePolonia merged commit adbdc56 into main Mar 26, 2026
16 checks passed
@SantiagoDePolonia SantiagoDePolonia deleted the refactor/model-selector-resolution-flow branch April 4, 2026 11:36
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.

1 participant