Skip to content

[feat] Agents keep the project sidebar (flat agent navigation) - #5945

Merged
mmabrouk merged 4 commits into
release/v0.112.0from
feat/agent-flat-navigation
Aug 12, 2026
Merged

[feat] Agents keep the project sidebar (flat agent navigation)#5945
mmabrouk merged 4 commits into
release/v0.112.0from
feat/agent-flat-navigation

Conversation

@mmabrouk

Copy link
Copy Markdown
Member

Context

Opening an agent used to swap the whole sidebar into an agent-context rail (Back, Overview, Playground, Sessions, Registry, Evaluations, Observability). Mahmoud redesigned this: agents are first-class rows in the project sidebar, and entering one should not take over navigation. Classic prompt apps keep the contextual rail unchanged.

Changes

For agents only: clicking an agent keeps the project sidebar and opens that agent's overview; clicking a session keeps the sidebar and opens the playground on that session; Registry, Evaluations, and per-app Observability entries are removed for agents in every mode (the pages stay URL-reachable; only navigation is removed). The project rail is reordered to Home → Prompts → Agents → Sessions, the Agents entry reads as selected across an agent's routes, and while an app's agent-ness is still loading, the sidebar holds its current rail instead of flashing the wrong one (unit-tested guard). The sidebar's session rows also gain quality-of-life changes that share these files: the visible cap rises from 7 to 14 (constant exported and test-pinned on the parent branch) and hovering a session shows the owning agent's name.

Classic prompt apps behave exactly as before: they still swap to the contextual rail with all entries.

Tests / notes

What to QA

  • Click an agent in the sidebar: overview opens, sidebar does not change, Agents row highlighted.
  • Click a session under Sessions: the agent playground opens on that session, sidebar unchanged; hover a session row first: tooltip names the agent.
  • Hard-reload an agent playground URL: no flash of the old agent-context rail.
  • Open a classic Prompt app: the contextual rail still appears with all its entries.
  • Regression: no Registry/Evaluations/Observability entries appear anywhere for an agent, in either Classic mode state.

@dosubot dosubot Bot added the size:L This PR changes 100-499 lines, ignoring generated files. label Aug 11, 2026
@vercel

vercel Bot commented Aug 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Error Error Aug 12, 2026 9:16am

Request Review

@dosubot dosubot Bot added enhancement New feature or request frontend labels Aug 11, 2026
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Improved sidebar navigation for agent, app, evaluator, and observability workflows.
    • Agent pages remain highlighted while navigating related routes.
    • Added contextual tooltips and “Show all” behavior for sidebar entries.
    • Sidebar view selection now preserves the active workflow during agent-state transitions.
  • Bug Fixes

    • Corrected route matching for trailing slashes and nested paths.
    • Improved sidebar item selection across dynamic and workflow routes.
  • Tests

    • Added coverage for sidebar routing, tooltips, item limits, and fallback behavior.

Walkthrough

The sidebar now supports explicit route matching, dynamic child tooltips, agent-aware navigation, and shared session limits. Sidebar view resolution uses early agent state and preserves the workflow view while agent status is unresolved.

Changes

Sidebar navigation behavior

Layer / File(s) Summary
Route matching contracts and selection
web/oss/src/components/Sidebar/engine/types.ts, web/oss/src/components/Sidebar/engine/SidebarShell.tsx
Sidebar items support explicit matchLinks. Matching handles empty lists, trailing slashes, exactness, specificity, and dynamic routes.
Dynamic entry metadata and rendering
web/oss/src/components/Sidebar/dynamic/types.ts, web/oss/src/components/Sidebar/dynamic/registry.ts, web/oss/src/components/Sidebar/dynamic/useSidebarDynamicChildren.ts, web/oss/src/components/Sidebar/dynamic/useSidebarDynamicChildren.test.ts, web/oss/src/components/Sidebar/engine/SidebarMenu.tsx
Dynamic entries propagate tooltips and project-prefixed match links. Session rows use the shared visibility limit and avoid unintended route matches. Agent rows match all app routes.
Project sidebar navigation
web/oss/src/components/Sidebar/hooks/useSidebarConfig/index.tsx
Agents appear before Sessions. Registry navigation is limited to app workflows. Evaluations and Observability also support evaluator workflows.
Agent-aware sidebar view resolution
web/oss/src/components/Sidebar/scopes/viewRegistry.ts, web/oss/src/components/Sidebar/scopes/viewRegistry.test.ts, web/oss/src/components/Layout/Layout.tsx
View resolution uses agent state and the current view ID. Layout commits the resolved view after render. Tests cover route, state, fallback, settings, and held-view cases.

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

Sequence Diagram(s)

sequenceDiagram
  participant Layout
  participant AgentState
  participant ViewRegistry
  participant Sidebar
  Layout->>AgentState: read early agent state
  Layout->>ViewRegistry: resolve view with state and current view
  ViewRegistry-->>Layout: return sidebar view
  Layout->>Sidebar: render resolved navigation
  Sidebar->>Sidebar: match configured route links
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the primary change: agents retain the project sidebar with flat navigation.
Description check ✅ Passed The description directly explains the sidebar behavior, route handling, session updates, tests, and validation for this changeset.
✨ Finishing Touches 💡 1
🛠️ Fix failing CI checks 💡
  • Create stacked PR
  • Commit on current branch
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/agent-flat-navigation

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 commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Preview URL https://gateway-pr-5945.up.railway.app/w
Project agenta-oss-clone-spike
Image tag pr-5945-775d33a
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-08-12T09:28:17.424Z

@mmabrouk

Copy link
Copy Markdown
Member Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@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


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: CHILL

Plan: Pro Plus

Run ID: 7deeed94-95bd-4fac-8ac0-2acf2b7bedbc

📥 Commits

Reviewing files that changed from the base of the PR and between 57a092d and b3b0ee1.

📒 Files selected for processing (11)
  • web/oss/src/components/Layout/Layout.tsx
  • web/oss/src/components/Sidebar/dynamic/registry.ts
  • web/oss/src/components/Sidebar/dynamic/types.ts
  • web/oss/src/components/Sidebar/dynamic/useSidebarDynamicChildren.test.ts
  • web/oss/src/components/Sidebar/dynamic/useSidebarDynamicChildren.ts
  • web/oss/src/components/Sidebar/engine/SidebarMenu.tsx
  • web/oss/src/components/Sidebar/engine/SidebarShell.tsx
  • web/oss/src/components/Sidebar/engine/types.ts
  • web/oss/src/components/Sidebar/hooks/useSidebarConfig/index.tsx
  • web/oss/src/components/Sidebar/scopes/viewRegistry.test.ts
  • web/oss/src/components/Sidebar/scopes/viewRegistry.ts

Comment thread web/oss/src/components/Layout/Layout.tsx Outdated
@mmabrouk

Copy link
Copy Markdown
Member Author

Manual review of record — #5945 (agents keep the project sidebar / flat navigation)

Posting this on the record because CodeRabbit's automated review is skipped on this PR: its base is a feature branch (fix/empty-sessions-and-drive-views) rather than a release branch, and CodeRabbit does not review PRs against non-configured bases. The trap is that the skip shows up as a green "CodeRabbit" check reading "Review skipped: reviews are disabled for this base branch" — indistinguishable at a glance from a completed clean review. Before this pass, #5945 had zero reviews. An on-demand @coderabbitai full review did subsequently run and produced one comment (Layout.tsx, fixed in 194a28d2); this manual pass covers the rest.

Verdict: sound. One issue found and fixed; no blocking findings remaining.

Fixed

Layout.tsx wrote currentSidebarViewIdRef.current during render. A render React abandons could leave behind a view id that never committed, which matters because resolveSidebarView only holds the workflow rail when currentViewId === WORKFLOW_SIDEBAR_SCOPE_ID — so a phantom id could hold a rail that was never on screen. Moved to the commit phase in 194a28d2, using the repo's existing useIsomorphicLayoutEffect rather than a bare useLayoutEffect, since this file is server-rendered under the pages router and would otherwise warn on every SSR pass.

Checked and correct

The empty-matchLinks contract holds. This was the failure mode I most expected: childMatchPaths: () => [] on sessions is documented as "keeps the row out of route matching", and a matchLinks?.length ? matchLinks : [link] style fallback would have silently inverted it into "match the link". SidebarShell.tsx:64 uses ??, not ||:

const matchLinks = item.matchLinks ?? (item.link ? [item.link] : [])

so the empty array survives and the opt-out works. Sessions correctly do not fight the Agents row for the highlight — right, since every session of an agent shares one /apps/<id>/playground URL and the path genuinely cannot distinguish them.

The tooltip data is real. getTooltip: (session) => session.agentName ?? undefined is backed by an actual field: agentName is on SessionSidebarRef and populated in sessionsSource.ts. It is not a silently-always-undefined feature. (Its resolution cost is addressed in a separate finding on #5944.)

Rail-swap flash handling is deliberate and coherent. Holding the workflow rail while agentState === "unknown" — but only when that rail is already up — is the right shape: it prevents a visible swap for classic apps without inventing a rail on cold load. Restricting workflowCategories to ["app"] for Registry and ["app", "evaluator"] for Evaluations/Traces closes the same flash from the other side, so those rows never appear for an agent even during the unresolved instant.

One accepted trade worth stating explicitly

On a cold load straight into a classic (non-agent) app URL, agentState is unknown and there is no rail to hold, so resolveSidebarView falls through to the base project rail. During that window the Agents row also matches, because its matchLinks includes the ${baseAppURL}/ prefix — so a classic app briefly shows the project rail with Agents highlighted, until the workflow type resolves and the view swaps.

The code's comment justifies the prefix with "Only agents reach /apps/<id> with the project rail up", which is true in the settled state but not during that cold-load instant. The author documented the fallback choice deliberately ("a cold load with no rail to hold lands on the base view, which is where agents — the common case — belong anyway"), and I agree with the trade: agents are the common path, and the alternative costs a flash for them instead. Flagging it only so it is a known transient rather than a future bug report.

Verification

tsc --noEmit clean on both @agenta/oss and @agenta/ee; eslint and prettier clean on every changed file; the PR's own new suites pass along with the rest of the sidebar tests (4 files / 19 tests, including viewRegistry.test.ts and useSidebarDynamicChildren.test.ts). The new tests are well-targeted — viewRegistry.test.ts covers the agent/non-agent/unknown matrix including the hold, which is the part most likely to regress.

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@mmabrouk Thanks for the detailed manual review record.

The render-to-commit correction in 194a28d2 addresses the abandoned-render state risk. The matchLinks validation also confirms that session rows remain excluded from route selection.

The cold-load Agents highlight is documented as an accepted transient. The stated test, type-check, lint, and formatting validation supports the non-blocking verdict.

🐇


✏️ Learnings added
Learnt from: mmabrouk
URL: https://github.com/Agenta-AI/agenta/pull/5945

Timestamp: 2026-08-11T20:31:26.528Z
Learning: For PR `#5945`, `Layout.tsx` must update `currentSidebarViewIdRef.current` in `useIsomorphicLayoutEffect`, not during render. `resolveSidebarView` uses this committed sidebar view ID to preserve the workflow sidebar while `agentState === "unknown"`, so a render that React abandons must not change the stored value.

Learnt from: mmabrouk
URL: https://github.com/Agenta-AI/agenta/pull/5945

Timestamp: 2026-08-11T20:31:26.528Z
Learning: In `web/oss/src/components/Sidebar/engine/SidebarShell.tsx`, an empty `SidebarConfig.matchLinks` array explicitly disables route matching. Preserve this contract with nullish fallback semantics such as `item.matchLinks ?? (item.link ? [item.link] : [])`; do not replace it with a length- or truthiness-based fallback.

Learnt from: mmabrouk
URL: https://github.com/Agenta-AI/agenta/pull/5945

Timestamp: 2026-08-11T20:31:26.528Z
Learning: For the agent sidebar navigation, a cold load of a classic non-agent app can temporarily render the base project sidebar with Agents selected while `agentState` is `unknown`. This is an accepted trade: `resolveSidebarView` does not hold a workflow sidebar unless it was already committed, which avoids an incorrect workflow rail on cold loads.

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

You are interacting with an AI system.

@mmabrouk
mmabrouk force-pushed the fix/empty-sessions-and-drive-views branch from 35bb6b8 to 3119b84 Compare August 11, 2026 20:56
@mmabrouk
mmabrouk force-pushed the feat/agent-flat-navigation branch from a530da5 to 523886e Compare August 11, 2026 20:56
@mmabrouk

Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@mmabrouk

Copy link
Copy Markdown
Member Author

🤖 The AI agent says:

Addressed both review findings in e0e553dc.

  • P2: Layout.tsx now observes whether the latest-revision lookup is still pending. When the lookup finishes without a type, including request failures normalized to null, sidebar resolution settles unknown app state to non-agent and selects the workflow sidebar. Known agents still keep the project sidebar. Added coverage for the settled fallback, the in-flight state, known agents, and non-app routes.
  • P3: Condensed every narrative comment introduced by this PR across the changed sidebar files to one short line.

Validation: 14 focused sidebar tests pass. The OSS TypeScript check, targeted ESLint, Prettier, and git diff --check also pass.

@mmabrouk mmabrouk left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

lgtm

@mmabrouk mmabrouk added the lgtm This PR has been approved by a maintainer label Aug 12, 2026
@mmabrouk
mmabrouk force-pushed the fix/empty-sessions-and-drive-views branch from ca3cb2e to b80d8af Compare August 12, 2026 09:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request frontend lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant