Skip to content

feat(routing): add routing profiles dashboard editor - #1108

Merged
Wibias merged 25 commits into
devfrom
feat/routing-profiles-editor
Aug 6, 2026
Merged

feat(routing): add routing profiles dashboard editor#1108
Wibias merged 25 commits into
devfrom
feat/routing-profiles-editor

Conversation

@Wibias

@Wibias Wibias commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • add validated PUT and DELETE management endpoints for routing profiles while preserving the existing list and dry-run APIs
  • add a structured Routing page editor for profile ids, aliases, candidates, hard requirements, optimization weights, limits, and unknown-evidence policies
  • source provider and model suggestions from the existing config and model catalog, keep existing ids immutable, and surface server validation without mutating invalid config
  • refresh the catalog after successful profile writes and removals
  • add focused management, editor-data, and page-wiring tests plus dashboard usage documentation

Verification

  • strict TypeScript semantic harness for RoutingProfiles.tsx and the editor data module: passed
  • strict TypeScript semantic harness for routing-profile-routes.ts: passed
  • Node runtime assertions for payload conversion, error extraction, and provider model filtering: passed
  • branch updated to current dev (ef131787) before opening this PR
  • full Bun test/typecheck/lint/build suite: delegated to GitHub Actions because this connector-only environment has no Bun installation or runnable repository checkout
  • screenshot: not attached from this environment because the dashboard cannot be launched here; this remains a draft until CI and visual review complete

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Summary by CodeRabbit

  • New Features

    • Added a full Routing Profile Editor for creating, editing, saving, cancelling, and deleting profiles.
    • Added controls for candidates, requirements, optimization, limits, and unknown-evidence handling.
    • Added provider-aware model selection, filtering, validation, revision handling, status messages, and dry-run error feedback.
    • Added management API support for creating, updating, deleting, and persisting routing profiles.
    • Added localized routing profile messages across supported languages.
  • Documentation

    • Added a guide covering profile creation, immutable IDs, validation, persistence, dry-run evaluation, API usage, and save payloads.

@coderabbitai

coderabbitai Bot commented Aug 6, 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

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d5145429-e591-42d5-b8db-a251c20d4d6e

📥 Commits

Reviewing files that changed from the base of the PR and between bcec06d and fcd713b.

📒 Files selected for processing (2)
  • src/server/management/routing-profile-routes.ts
  • tests/routing-profile-management-editor.test.ts

📝 Walkthrough

Walkthrough

The change adds an editable Routing Profile Editor, shared draft and DTO utilities, management API create/update/delete operations, validation and persistence tests, localization, and user documentation.

Changes

Routing Profile Editor

Layer / File(s) Summary
Editor data contracts and serialization
gui/src/routing-profile-editor-data.ts, tests/routing-profile-editor-data.test.ts
Adds DTO and draft types, defaults, conversion helpers, PUT serialization, response parsing, provider model filtering, and focused tests.
Management API persistence and reconciliation
src/server/management/routing-profile-routes.ts, tests/routing-profile-management-editor.test.ts
Adds PUT and DELETE handlers with validation, normalization, persistence, state reconciliation, catalog refresh, alias migration, and API coverage.
Editable GUI profile flow
gui/src/pages/RoutingProfiles.tsx, gui/tests/routing-profiles.test.tsx, tests/routing-intelligence-ui.test.ts, gui/src/i18n/*.ts
Replaces the read-only panel with editable controls for candidates, requirements, optimization, limits, and evidence modes. Adds guarded loading, CRUD flows, status notices, localization, and UI coverage.
Editor API and workflow documentation
docs-site/src/content/docs/guides/routing-profile-editor.md
Documents profile creation, immutable IDs, validation, persistence, dry-run behavior, management endpoints, and an example request payload.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested reviewers: lidge-jun, ingwannu

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant RoutingProfiles
  participant RoutingProfileRoutes
  participant Configuration
  participant CodexCatalog
  User->>RoutingProfiles: Edit and save routing profile
  RoutingProfiles->>RoutingProfileRoutes: PUT serialized profile
  RoutingProfileRoutes->>Configuration: Persist normalized profile
  RoutingProfileRoutes->>CodexCatalog: Reconcile and refresh catalog
  RoutingProfileRoutes-->>RoutingProfiles: Return saved profile
  RoutingProfiles-->>User: Show updated profile and status
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.90% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding a routing profiles dashboard editor.
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 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/routing-profiles-editor

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.

@github-actions github-actions Bot added the enhancement New feature or request label Aug 6, 2026
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Deterministic PR hygiene checks passed.

Wibias added 13 commits August 6, 2026 09:42
…rving wrapper

The PUT and DELETE routing-profile handlers assigned the guarded saver to a
local named \saveConfig\, which trips the config-save-boundary guard that
forbids bare saveConfig calls from live-config management writers. Alias it
to \save\ like the other management routes so test 4/4 goes green.
…ent specs

- Replace the inline min/max/step ternary chain in the numeric requirement
  inputs with a per-key spec table (single source for constraints).
- Merge the status/statusOk state pair into one {message, ok} | null state,
  collapsing the notify helper and the repeated reset pairs.

Behavior-preserving: same input attributes emitted, same notice behavior
(errors persist, success auto-clears after 5s).
The numeric requirement spec object has a union shape ({min, step} for
minContextWindow vs {min, max, step} for minQuotaHeadroom), so indexing
[NUMERIC_REQUIREMENT_SPEC[key].max] fails the GUI typecheck. Add
max: undefined to the minContextWindow entry so both members share the
same shape; behavior is unchanged (max={undefined} renders no max
attribute).
@Wibias

Wibias commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

[GD] Verdict: gated

TLDR

  • PR: #1108 — feat(routing): add routing profiles dashboard editor
  • Head: f67753e0 on dev (mergeStateStatus: UNSTABLE, up to date with dev)
  • Decision: useful and code-clean; gated because the PR is a draft and one required check (react-doctor) is red from a toolchain/diff-derivation failure, not code.
  • Usefulness: delivers real value — validated PUT/DELETE routing-profile management endpoints plus a structured Routing-page editor for config.routingProfiles, with docs and tests.
  • Bugs: one PR-introduced blocker found and fixed in-PR (config-save-boundary); none remaining.
  • Security: none — new endpoints inherit the standard management auth (admin token / GUI session + CSRF); validation is strict (id/alias patterns, provider existence/enabled, duplicate candidates, numeric ranges, weights); no injection/SSRF/new secrets.
  • Spec / standards: clean — docs match implementation (create/update modes, validation rules, dry-run never dispatches upstream); i18n keys exist in all locales.
  • Reviews: CodeRabbit skipped (draft); pr-hygiene passed; no human feedback, no open threads.
  • Base / CI: updated to latest dev (merged a5b37827, which fixed the pre-existing issue-quality test). All 4 test shards, ci, macos, gates, npm-global, keyring, changes, hygiene, enforce-target, label green on f67753e0. react-doctor red (toolchain: "could not derive changed files from git" on the merge-ref checkout; fails in ~25s before any scan; no code annotations — infra, not PR code).
  • Gate: draft — the PR must be marked ready for review before it can proceed to merge.
  • Owner actions (foreign PR): none — this is our PR.
  • Bottom line: the feature is useful, the code is clean, and all PR-owned checks pass. To ship: mark the PR ready for review and re-run react-doctor (the toolchain failure typically clears once the merge-ref diff derivation succeeds; if it persists, it's an infra issue to raise separately, not this PR's code).
Full verdict

Semantic propagation

  • Concepts audited: routing profile id, alias, revision, candidates, require/optimize/limits/unknownEvidence; config-save guard; catalog convergence after writes.
  • Authoritative sources: config.routingProfiles (id/alias/candidates/fields), normalizeRoutingProfile (revision digest, optimize/unknownEvidence defaults), saveConfigPreservingClaudeCode (persistence).
  • Producers and consumers checked: PUT/DELETE routes → config.routingProfiles; GET DTO, dry-run, router (resolvePolicyProfileId), evaluator, and the config schema validator all consume the same normalized form; GUI and server field sets (4 optimize keys, 4 unknownEvidence keys, 10 require keys) match exactly.
  • Public/derived representations checked: GET DTO model via policyPublicModelId (alias-aware), revision digest, /api/models rows, dry-run trace revision.
  • Material variant partitions checked: all 4 unknownEvidence modes, all 4 optimize weights, all numeric/string/boolean require fields — GUI ↔ server equivalent.
  • Positive and negative assertions checked: PUT create/update/overwrite/unknown-id/alias-collision, DELETE present/absent, validation-before-mutation, catalog refresh after write.
  • Unmapped surfaces: none blocking. PUT rewrites the stored profile with normalized defaults (optimize, unknownEvidence, limits: {}) — behaviorally consistent with normalization-on-read (verified via manual UPDATE round-trip), but causes config churn and drops unknown keys on update; worth a follow-up if minimal stored diffs are desired.
  • Unproven equivalence assumptions: none blocking. Editor datalist suggests /api/models rows (provider+id), matching routing candidate semantics for the common case.
  • Representation mismatches: none.
  • Variant coverage gaps: model membership is not validated server-side (any non-empty string accepted) — pre-existing routingProfileIssues behavior, fail-soft in routing; not introduced by this PR.
  • Axis verdict: pass.

Linked: none.

Usefulness

Delivers the claimed value: previously config.routingProfiles could only be edited by hand; this PR adds validated PUT/DELETE management endpoints and a full dashboard editor (id, alias, candidates, hard requirements, optimization weights, limits, unknown-evidence policy), sources provider/model suggestions from the live config and model catalog, keeps ids immutable, surfaces server validation without mutating invalid config, and refreshes the catalog after writes. Documented in docs-site/src/content/docs/guides/routing-profile-editor.md with focused management, editor-data, and page-wiring tests.

Bugs / correctness

  • Method: bug-review.md — static analysis run (source read + focused tests); Bugbot/Cursor unavailable in this connector-only environment; complementary lenses applied (silent_failures, edge_cases, state_consistency, ui_async_state, parsing_serialization, retry_idempotency).
  • Findings:
    • Fixed in-PR: src/server/management/routing-profile-routes.ts assigned the guarded saver to a local named saveConfig, tripping the config-save-boundary guard (a bare saveConfig call on a live config re-clobbers hand-edited claudeCode). Fixed by aliasing to save like provider-routes.ts — commit 7538fe00c. Verified: config-save-boundary.test.ts passes; test 4/4 green in CI.
    • Minor (not blocking): candidate card key index-provider remounts the card on provider change (focus loss); PUT materializes normalized defaults in the stored config (config churn).
  • Fixed this session: 7538fe00c (save guard), plus two approved behavior-preserving simplifications in fbef06492/1cca4c853 (numeric requirement spec table; status/statusOk merged into one state).

Security

  • Scope reviewed: auth (management gate), input validation (id/alias patterns, provider existence/enabled, duplicate candidates, numeric ranges, weights), injection, secrets, catalog convergence.
  • Findings: none. New endpoints sit behind the existing requireManagementAuth (admin token or GUI session + CSRF for mutations); routingProfileIssues rejects malformed ids/aliases/providers; dry-run never dispatches upstream (verified in src/routing/evaluator.ts).
  • Fixed this session: none (no findings).

Spec / standards

  • Spec source: PR body + docs guide (no linked issue).
  • Gaps: none. Docs claims verified against code: naming/collision rules, provider existence/enabled, duplicate-candidate rejection, numeric range validation, "at least one optimize weight positive", config writer + live-state reconcile + catalog refresh on save, validation failures leave config unchanged, dry-run never dispatches upstream.

Reviews

  • Owners/maintainers: none open.
  • Bots (CodeRabbit/Codex/Bugbot): CodeRabbit skipped (draft); pr-hygiene passed; no open threads.

Base / CI

  • Behind/conflicts: updated to latest dev — merged a5b37827 (PR test(ci): accept the Copilot permission in the issue-quality workflow pin #1113, the issue-quality permission fix) in f67753e0; behind_by: 0.
  • Required checks on f67753e0: green — test 1/4, test 2/4, test 3/4, test 4/4, ci, macos, gates, npm-global {macos,ubuntu,windows}-latest, keyring {macos,ubuntu,windows}, changes, hygiene, enforce-target, label. Red: react-doctor — infra (fails ~25s during toolchain/diff-derivation; "could not derive the PR's changed files from git"; no code findings in annotations; workflow file byte-identical to base).
  • Local tip compile/tests: bun run typecheck pass; gui: bun run lint, bun run lint:i18n, bun run test (610 pass); bun test focused routing/config tests (116 pass incl. ci-workflows + config-save-boundary).

Simplification

  • Requested and applied (our PR, approved): fbef06492 — per-key numeric-requirement spec table replacing the inline min/max/step ternary; 1cca4c853status/statusOk merged into one {message, ok} | null state. Both behavior-preserving (same input attributes, same notice behavior); validated by typecheck, GUI lint, i18n lint, 610 GUI tests, and focused server tests.

Gate

Draft — reviewPolicy:draft blocks. react-doctor also red (infra).

Bottom line

The routing profiles dashboard editor is a useful, well-tested feature. The PR-introduced config-save-boundary failure is fixed, the branch is updated to latest dev, and all PR-owned checks pass. The remaining work is operational, not code: mark the PR ready for review (it is currently a draft) and get react-doctor to pass — the failure is a toolchain/diff-derivation issue on the merge-ref checkout, not a finding in this PR's code. Once the draft gate clears and react-doctor is green, this is merge-ready.

@Wibias
Wibias marked this pull request as ready for review August 6, 2026 09:42

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

🤖 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 `@gui/src/pages/RoutingProfiles.tsx`:
- Around line 403-405: The create-profile button in RoutingProfiles should use a
dedicated routing.createProfile i18n key instead of routing.detail; add the key
to every locale under gui/src/i18n with the appropriate translated label. Update
docs-site/src/content/docs/guides/routing-profile-editor.md at line 11 and the
ja, ko, ru, and zh-cn localized pages to document the new label.

In `@gui/src/routing-profile-editor-data.ts`:
- Around line 167-205: Update routingProfilePutBody to accept or derive the
required write mode and include mode ("create" or "update") alongside id and
profile in its returned body. Update all callers and routing-profile-editor-data
tests to provide the mode and assert the complete serialized request contract.

In `@gui/tests/routing-profiles.test.tsx`:
- Around line 145-149: Update requirementSelect to first locate the fieldset
whose legend matches the rendered translation for t("routing.require"), then
search only that fieldset’s labels for the requested key. Preserve the existing
null behavior when the requirements fieldset or matching select is absent.

In `@tests/routing-profile-management-editor.test.ts`:
- Around line 148-171: Add a focused test beside “PUT create refuses to
overwrite an existing profile” that sends a PUT request for existing profile
“fast” with mode “update” and replacement candidates. Assert the response
succeeds, its payload contains the normalized updated profile,
config.routingProfiles.fast is replaced accordingly, and the dependency counters
confirm exactly one save and one catalog refresh.
🪄 Autofix

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: ASSERTIVE

Plan: Pro Plus

Run ID: d7ed67d8-617b-4d0d-ad78-46c4de820ae9

📥 Commits

Reviewing files that changed from the base of the PR and between a5b3782 and f67753e.

📒 Files selected for processing (8)
  • docs-site/src/content/docs/guides/routing-profile-editor.md
  • gui/src/pages/RoutingProfiles.tsx
  • gui/src/routing-profile-editor-data.ts
  • gui/tests/routing-profiles.test.tsx
  • src/server/management/routing-profile-routes.ts
  • tests/routing-intelligence-ui.test.ts
  • tests/routing-profile-editor-data.test.ts
  • tests/routing-profile-management-editor.test.ts

Comment thread gui/src/pages/RoutingProfiles.tsx
Comment thread gui/src/routing-profile-editor-data.ts Outdated
Comment thread gui/tests/routing-profiles.test.tsx
Comment thread tests/routing-profile-management-editor.test.ts

@Ingwannu Ingwannu left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

The runtime/API feature is useful and the core CI is green, but the current head is not ready for approval yet.

I checked the latest f67753e0 increment after the self-verdict. The live saveProfile caller does append mode, so the current GUI request is not missing it at runtime. However, the newest CodeRabbit review arrived after that verdict and has four still-actionable items that should be resolved on this head:

  1. The create action is rendered with routing.detail; use a dedicated localized create-profile label in every locale and keep the guide aligned.
  2. Make routingProfilePutBody own the full server request contract, including mode, instead of relying on a caller-side spread that its unit tests cannot verify.
  3. Scope the requirement-select test helper to the requirements fieldset so duplicate labels elsewhere cannot produce a false pass.
  4. Add the missing successful mode: "update" management regression proving replacement plus exactly one save and one catalog refresh.

These are small but relevant: the first is visible behavior, the second prevents the editor helper and server contract from drifting, and the fourth covers the only mutation mode not presently proven end to end. The repeated react-doctor failure also remains red; even if it is diff-derivation infrastructure rather than code, required checks must be green or formally waived by the owner after inspecting the job.

Please address or rebut each current finding with exact-head evidence, rerun React Doctor, and then request owner review for the GUI/text surface. I am not merging GUI/text work autonomously.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f67753e047

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/server/management/routing-profile-routes.ts
Comment thread gui/src/pages/RoutingProfiles.tsx Outdated
Comment thread gui/src/pages/RoutingProfiles.tsx Outdated
Comment thread gui/src/pages/RoutingProfiles.tsx
Three findings from react-doctor 0.9.3:

- saveProfile/removeProfile read the fetch Response body before checking
  response.ok, so an HTTP error payload was parsed as success. Route both
  through readJsonIfOk (which checks res.ok before consuming) and read the
  structured error body explicitly on the non-OK branch.
- the candidate card used an index-derived React key. Draft candidates now
  carry a stable client-side key (newDraftCandidate) that is stripped by
  routingProfilePutBody and never reaches the server; add/update keep it.

react-doctor --scope changed --base upstream/dev: No issues found.
Verified: root+GUI typecheck, GUI lint, 610 GUI tests, 128 focused server
tests.

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
gui/src/pages/RoutingProfiles.tsx (2)

387-390: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Move these user-visible strings into locale resources.

Both sites render untranslated text in the Routing dashboard.

  • gui/src/pages/RoutingProfiles.tsx#L387-L390: Replace the dry-run ${response.status} fallback with a localized status-aware message.
  • gui/src/pages/RoutingProfiles.tsx#L633-L648: Map each UnknownEvidenceMode value to a localized option label while preserving the enum value.

As per path instructions, user-visible strings go through the i18n locale files rather than hardcoded text.

🤖 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 `@gui/src/pages/RoutingProfiles.tsx` around lines 387 - 390, The dry-run error
fallback in RoutingProfiles.tsx:387-390 must use a localized status-aware
message instead of the hardcoded `dry-run ${response.status}` string; update the
relevant i18n locale resources and consume them through the page’s existing
translation mechanism. At RoutingProfiles.tsx:633-648, map every
UnknownEvidenceMode value to a localized option label while preserving the
original enum value for selection and submission.

Source: Path instructions


81-93: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Validate all nested profile fields before accepting a profile.

parseProfiles accepts a profile without require, optimize, limits, or unknownEvidence. load then passes it to routingProfileDraftFromDto at Line 220. That conversion dereferences nested fields such as profile.require.minContextWindow, so a malformed management response fails the load path.

Validate the complete DTO shape before returning it from parseProfiles. Reject invalid profiles or show a controlled load error. Add a regression test for a response that omits a required nested object.

🤖 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 `@gui/src/pages/RoutingProfiles.tsx` around lines 81 - 93, Update parseProfiles
to validate every required nested RoutingProfileDto field, including require,
optimize, limits, and unknownEvidence, before accepting a profile; reject
profiles with missing or malformed nested objects so routingProfileDraftFromDto
cannot dereference invalid data. Add a regression test covering a management
response that omits a required nested object and verify loading fails in the
existing controlled manner.
🤖 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.

Outside diff comments:
In `@gui/src/pages/RoutingProfiles.tsx`:
- Around line 387-390: The dry-run error fallback in RoutingProfiles.tsx:387-390
must use a localized status-aware message instead of the hardcoded `dry-run
${response.status}` string; update the relevant i18n locale resources and
consume them through the page’s existing translation mechanism. At
RoutingProfiles.tsx:633-648, map every UnknownEvidenceMode value to a localized
option label while preserving the original enum value for selection and
submission.
- Around line 81-93: Update parseProfiles to validate every required nested
RoutingProfileDto field, including require, optimize, limits, and
unknownEvidence, before accepting a profile; reject profiles with missing or
malformed nested objects so routingProfileDraftFromDto cannot dereference
invalid data. Add a regression test covering a management response that omits a
required nested object and verify loading fails in the existing controlled
manner.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 65c854bd-e39a-4e3c-b684-20084df9f215

📥 Commits

Reviewing files that changed from the base of the PR and between f67753e and 4bfc4cc.

📒 Files selected for processing (3)
  • gui/src/pages/RoutingProfiles.tsx
  • gui/src/routing-profile-editor-data.ts
  • tests/routing-profile-editor-data.test.ts

CodeRabbit, Codex connector, and owner review items on #1108:

- routing.createProfile key replaces the reused routing.detail on the create
  button; guide synced; localized in all six locales.
- routingProfilePutBody now owns the serialized request contract: mode is
  part of the returned body (not a caller-side spread), and updates carry
  expectedRevision for optimistic concurrency.
- requirementSelect test helper scopes to the Hard requirements fieldset so
  health/cost/quota keys in other fieldsets cannot false-match.
- management regression test covers the mode:update success path (one save,
  one catalog refresh) plus a 409 stale-revision conflict.
- dry-run error fallback and UnknownEvidenceMode option labels are localized.
- parseProfiles validates the complete nested DTO shape so a malformed
  management response cannot crash the load path; GUI regression test added.
- PUT update migrates config references on alias change (disabledModels,
  subagentModels, injectionModel, shadowCallIntercept, claudeCode) and syncs
  Claude agent defs, mirroring the /api/combos pattern.
- delete confirmation and candidate remove aria-label are localized.

react-doctor 0.9.3 --scope changed --base upstream/dev: No issues found.
Verified: root+GUI typecheck, GUI lint+i18n lint, 611 GUI tests, 137 focused
server tests.

@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 `@src/server/management/routing-profile-routes.ts`:
- Around line 159-213: Update migrateProfileModelReferences to migrate
config.subagentModelFallback entries using the same deduplication logic as
subagentModels, and migrate both keys and values of claudeCode.modelMap so old
aliases remain matched for rerouting. Preserve shouldSyncClaudeAgentDefs
behavior for migrated agent references, and add coverage in
routing-profile-management-editor tests.
🪄 Autofix

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: ASSERTIVE

Plan: Pro Plus

Run ID: 869d71c9-3452-4d5e-9f2b-731ebcaba8f3

📥 Commits

Reviewing files that changed from the base of the PR and between 4bfc4cc and cf3d4b5.

📒 Files selected for processing (13)
  • docs-site/src/content/docs/guides/routing-profile-editor.md
  • gui/src/i18n/de.ts
  • gui/src/i18n/en.ts
  • gui/src/i18n/ja.ts
  • gui/src/i18n/ko.ts
  • gui/src/i18n/ru.ts
  • gui/src/i18n/zh.ts
  • gui/src/pages/RoutingProfiles.tsx
  • gui/src/routing-profile-editor-data.ts
  • gui/tests/routing-profiles.test.tsx
  • src/server/management/routing-profile-routes.ts
  • tests/routing-profile-editor-data.test.ts
  • tests/routing-profile-management-editor.test.ts

Comment thread src/server/management/routing-profile-routes.ts
…s change

CodeRabbit follow-up on cf3d4b5: migrateProfileModelReferences rewrote
subagentModels and claudeCode.modelMap values but missed the sibling
config.subagentModelFallback chain and modelMap keys, which are the inbound
ids matched for reroute in src/claude/inbound.ts. Both now follow an alias
rename, with the migration regression test extended to cover them.

@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 `@src/server/management/routing-profile-routes.ts`:
- Around line 211-216: Update the modelMap migration in the surrounding
routing-profile handling to detect duplicate keys produced by
migrateAgentReference before assigning the migrated map. Reject conflicting
mappings (or apply a clearly defined merge policy) instead of allowing
Object.fromEntries to overwrite entries, and add a regression test covering both
colliding source keys with different targets.
🪄 Autofix

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: ASSERTIVE

Plan: Pro Plus

Run ID: b52977d1-6213-4141-8992-0ff3b6fd74f0

📥 Commits

Reviewing files that changed from the base of the PR and between cf3d4b5 and bcec06d.

📒 Files selected for processing (2)
  • src/server/management/routing-profile-routes.ts
  • tests/routing-profile-management-editor.test.ts

Comment thread src/server/management/routing-profile-routes.ts
CodeRabbit follow-up on bcec06d: migrating modelMap keys via
Object.fromEntries silently drops a mapping when the map already contains the
new alias as a key with a different target. Detect that collision before any
mutation and reject the update with 409 alias_reference_conflict so no
mapping is lost; regression test covers both keys with different targets.
@Wibias
Wibias merged commit 75f384c into dev Aug 6, 2026
23 checks passed
@Wibias
Wibias deleted the feat/routing-profiles-editor branch August 6, 2026 10:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants