Skip to content

feat: add ability to edit alias target in dashboard - #348

Merged
njbrake merged 3 commits into
mainfrom
fix/alias-edit-target
Jul 22, 2026
Merged

feat: add ability to edit alias target in dashboard#348
njbrake merged 3 commits into
mainfrom
fix/alias-edit-target

Conversation

@njbrake

@njbrake njbrake commented Jul 21, 2026

Copy link
Copy Markdown
Member

Description

The dashboard could create and delete stored aliases but had no way to change an alias's target model after creation. This adds an Edit button on stored alias rows that opens a form pre-filled with the current target, allowing the operator to shift the alias to a different model.

The backend POST /v1/aliases already performs an upsert (update if the name exists, create otherwise), so the frontend reuses useCreateAlias. The name is displayed read-only in the edit form since it is the lookup key; renaming requires delete + recreate.

PR Type

  • New Feature

Relevant issues

Fixes #341

Checklist

  • I understand the code I am submitting.
  • I have added or updated tests that cover my change (tests/unit, tests/integration).
  • I ran the Definition of DoD checks locally (npm --prefix web run typecheck, npm --prefix web test).
  • Documentation was updated where necessary.
  • If the API contract changed, I regenerated the OpenAPI spec (uv run python scripts/generate_openapi.py).

AI Usage

  • AI was used for drafting/refactoring.

AI Model/Tool used: Laguna S 2.1 from Poolside AI

Any additional AI details you'd like to share:

  • I am an AI Agent filling out this form (check box if true)

Summary

  • Added dashboard support for editing an existing alias’s target model.
  • Added an edit form with the alias name locked and the target pre-filled.
  • Ensured create and edit forms cannot be open at the same time.
  • Added regression tests for editing and form visibility.
  • Rebuilt the dashboard bundle to include the updated changes.

@njbrake
njbrake temporarily deployed to integration-tests July 21, 2026 20:09 — with GitHub Actions Inactive
@coderabbitai

coderabbitai Bot commented Jul 21, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@njbrake, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 24 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d38d0765-4d7e-4172-a15c-38a164ed92cf

📥 Commits

Reviewing files that changed from the base of the PR and between 2ec66db and fd7dd10.

📒 Files selected for processing (2)
  • src/gateway/static/dashboard/assets/index-CbOYTKpN.js
  • src/gateway/static/dashboard/index.html

Walkthrough

Changes

Dashboard alias editing

Layer / File(s) Summary
Alias edit flow
web/src/pages/AliasesPage.tsx, web/src/pages/AliasesPage.test.tsx
Stored aliases can be edited through a target-only form, with mutually exclusive create/edit states and tests covering submission and visibility behavior.
Dashboard runtime publication
src/gateway/static/dashboard/index.html, src/gateway/static/dashboard/assets/index-EsDFkIUN.js
The dashboard references a refreshed hashed bundle containing updated modulepreload, React, React DOM, scheduler, and React Router runtime code.

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

Possibly related PRs

  • mozilla-ai/otari#227: Introduced the backend alias create/update contract used by the dashboard’s upsert behavior.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title uses the required Conventional Commit prefix and clearly describes the edit-alias change.
Description check ✅ Passed The description follows the template and includes the change summary, issue reference, checklist, and AI usage details.
Linked Issues check ✅ Passed The PR implements the requested alias edit capability so an alias can point to a different model, matching issue #341.
Out of Scope Changes check ✅ Passed The bundle and HTML asset hash updates appear to be necessary build artifacts for the dashboard changes, with no unrelated scope visible.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/alias-edit-target
✨ Simplify code
  • Create PR with simplified code
  • Commit simplified code in branch fix/alias-edit-target

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.

@njbrake njbrake changed the title Dashboard: add ability to shift alias to a different model feat: add ability to edit alias target in dashboard Jul 21, 2026
@njbrake
njbrake force-pushed the fix/alias-edit-target branch from 5113894 to d11a23c Compare July 21, 2026 20:20
@njbrake
njbrake temporarily deployed to integration-tests July 21, 2026 20:20 — with GitHub Actions Inactive
@njbrake
njbrake force-pushed the fix/alias-edit-target branch from d11a23c to a860ca3 Compare July 21, 2026 20:21
@njbrake
njbrake temporarily deployed to integration-tests July 21, 2026 20:21 — with GitHub Actions Inactive
@eiso

eiso commented Jul 21, 2026

Copy link
Copy Markdown

First open source PR from Laguna S2.1 ❤️ 😍

Thank you @njbrake

The dashboard could create and delete stored aliases but had no way to
change an alias's target model after creation. Add an Edit button on
stored alias rows that opens a form pre-filled with the current target,
allowing the operator to shift the alias to a different model.

The backend POST /v1/aliases already performs an upsert (update if the
name exists, create otherwise), so the frontend reuses useCreateAlias.
The name is displayed read-only in the edit form since it is the lookup
key; renaming requires delete + recreate.

Rebased on main and rebuilt dashboard bundle.

Fixes #341

Co-Authored-By: Laguna S 2.1 <noreply@poolside.ai>

Copilot AI 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.

Pull request overview

Adds dashboard support for editing an existing stored alias’ target model, reusing the existing alias upsert API (POST /v1/aliases) and extending the UI test suite to cover the new workflow.

Changes:

  • Add an “Edit” action for stored aliases and an edit form prefilled with the current target.
  • Reuse useCreateAlias for updates (backend upsert behavior) and invalidate alias/model queries on success.
  • Extend AliasesPage tests to verify updating a stored alias target.

Reviewed changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 1 comment.

File Description
web/src/pages/AliasesPage.tsx Adds edit form/state and “Edit” action for stored alias rows.
web/src/pages/AliasesPage.test.tsx Adds test coverage for editing an alias target and updates mock POST behavior to upsert by name.
src/gateway/static/dashboard/index.html Updates the built dashboard asset hash reference.
Comments suppressed due to low confidence (1)

web/src/pages/AliasesPage.tsx:140

  • adding and editing are not mutually exclusive. Since the table stays interactive while the create form is open, clicking "Edit" can result in both forms being rendered at once (and closing edit would still leave the create form open). Consider clearing the other mode when starting a new one so only one form can be open at a time.
          adding || editing ? null : (
            <Button variant="primary" onPress={() => setAdding(true)}>
              New alias
            </Button>
          )

Comment thread web/src/pages/AliasesPage.tsx Outdated

@khaledosman khaledosman left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Clean, small, well-tested. Reusing useCreateAlias for the upsert and showing the name read-only are the right calls. Approving, one UX nit inline.

Review created by Claude Code.

Comment thread web/src/pages/AliasesPage.tsx Outdated
<Td className="text-right whitespace-nowrap">
{alias.source === "stored" ? (
<span className="inline-flex items-center gap-2">
<Button size="sm" variant="ghost" onPress={() => setEditing(alias)}>Edit</Button>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit (UX): while the New-alias form is open (adding=true), these per-row Edit buttons stay active, so clicking one renders NewAliasForm and EditAliasForm at the same time. The header action is guarded (adding || editing) but the row buttons aren't. Consider closing adding when setEditing fires (or disabling row Edit while adding).

Claude Code

Opening the New alias form left the per-row Edit buttons active, so
clicking Edit rendered both forms stacked at once. Clear the other mode
when starting one: Edit closes adding, New alias closes editing. Add a
regression test and rebuild the dashboard bundle.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

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

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/src/pages/AliasesPage.tsx`:
- Line 153: Update the EditAliasForm rendering in AliasesPage so the component
receives a key derived from the edited alias name, forcing a remount when
editing changes from one alias to another while preserving the existing
conditional rendering and close 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0d92d456-a136-41bf-b493-7eb292eea217

📥 Commits

Reviewing files that changed from the base of the PR and between f7b96c5 and 2ec66db.

📒 Files selected for processing (4)
  • src/gateway/static/dashboard/assets/index-EsDFkIUN.js
  • src/gateway/static/dashboard/index.html
  • web/src/pages/AliasesPage.test.tsx
  • web/src/pages/AliasesPage.tsx

<ErrorBanner error={aliases.error} />

{adding ? <NewAliasForm initialTarget={initialTarget} onClose={() => setAdding(false)} /> : null}
{editing ? <EditAliasForm alias={editing} onClose={() => setEditing(null)} /> : null}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Missing key lets EditAliasForm show stale data when jumping between aliases mid-edit.

Here's a sneaky one: editing can go straight from alias A to alias B (user clicks "Edit" on a different row without closing the first form), but <EditAliasForm> has no key. Since React reuses the same component instance in that case, target's useState(alias.target) initializer won't re-run — so the form re-labels itself "Edit alias B" while target still holds A's (possibly edited) value. Saving would silently write the wrong target onto B.

The row list already keys by name (<Tr key={alias.name}>), so this is really just following that same convention one level up.

🐛 Proposed fix: force a remount when the edited alias changes
-      {editing ? <EditAliasForm alias={editing} onClose={() => setEditing(null)} /> : null}
+      {editing ? <EditAliasForm key={editing.name} alias={editing} onClose={() => setEditing(null)} /> : null}

Might also be worth a quick regression test (click Edit on row A, then Edit on row B without saving, assert the target input shows B's target) — happy to sketch one out if useful!

📝 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
{editing ? <EditAliasForm alias={editing} onClose={() => setEditing(null)} /> : null}
{editing ? <EditAliasForm key={editing.name} alias={editing} onClose={() => setEditing(null)} /> : null}
🤖 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 `@web/src/pages/AliasesPage.tsx` at line 153, Update the EditAliasForm
rendering in AliasesPage so the component receives a key derived from the edited
alias name, forcing a remount when editing changes from one alias to another
while preserving the existing conditional rendering and close behavior.

# Conflicts:
#	src/gateway/static/dashboard/assets/index-B4K-bUcs.js
#	src/gateway/static/dashboard/assets/index-EsDFkIUN.js
#	src/gateway/static/dashboard/assets/index-o4fHtIUd.js
#	src/gateway/static/dashboard/index.html
@njbrake
njbrake temporarily deployed to integration-tests July 22, 2026 00:06 — with GitHub Actions Inactive
@njbrake
njbrake merged commit 58ed119 into main Jul 22, 2026
7 checks passed
@njbrake
njbrake deleted the fix/alias-edit-target branch July 22, 2026 00:11
@njbrake

njbrake commented Jul 22, 2026

Copy link
Copy Markdown
Member Author

@eiso Thank you for releasing a wonderful model! I am seriously blown away with the quality of its reasoning and content, as well as the speed you can get because of the small-ish size. Keep em coming!

@njbrake njbrake mentioned this pull request Jul 22, 2026
4 tasks
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.

Dashboard: add ability to shift alias to a different model

4 participants