Skip to content

Focus dashboard on Agent Network for netbird.ai signups#708

Merged
mlsmaycon merged 18 commits into
mainfrom
feature/agent-network-source-onboarding
Jul 12, 2026
Merged

Focus dashboard on Agent Network for netbird.ai signups#708
mlsmaycon merged 18 commits into
mainfrom
feature/agent-network-source-onboarding

Conversation

@mlsmaycon

@mlsmaycon mlsmaycon commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Issue ticket number and link

Focuses the dashboard on the Agent Network surface for accounts that sign up
through netbird.ai, and takes those users through the Agent Network onboarding.
Fully user-reversible, and a no-op for every other account.

Signup source → account mark

  • A pre-auth hook captures ?signup_source=netbird.ai into localStorage so it
    survives the OIDC redirect (mirrors the AWS Marketplace capture hook).
  • Once authenticated, if the account is new (onboarding.signup_form_pending)
    and not already marked, the dashboard PUTs settings.agent_network_only=true,
    then awaits /accounts revalidation before clearing the source key (a useRef
    guard prevents duplicate writes). Awaiting the revalidation matters: clearing
    the key earlier left a window with neither the source optimism nor the stored
    setting, which briefly flipped the focused view off.

Mode resolution (backward-compatible)

  • useAgentNetworkMode() returns { only, enabled, loading } using nullish
    semantics: an explicit agent_network_only (true or false) always wins, so a
    user can opt out even when a deployment config flag is on; when the setting is
    absent, a pending netbird.ai signup (optimistic) or the existing
    NETBIRD_AGENT_NETWORK_ONLY / _ENABLED config decides. With no account
    setting, behavior is exactly as before — the setting is purely additive.
  • Navigation, the agent-network route guard, control-center, and related fetch
    gates read the resolver instead of the config functions. The route guard waits
    for account load to avoid a redirect flash.

Onboarding

  • netbird.ai signups run the Agent Network onboarding: the signup form (now
    shown on cloud, not only self-hosted) followed by the agent-network flow.
  • The onboarding form is chosen from signup_source synchronously at render, so
    a netbird.ai arrival commits to the Agent Network form on first paint and the
    regular form is never shown to them, even when the backend is slow to persist
    the setting.

Opt-out

  • A "Agent Network focused view" toggle in Client Settings sets
    settings.agent_network_only=false, which the resolver honors over any config
    flag.

Tests

  • E2E specs for the focused-view menu/routes and for onboarding form selection
    (which form shows first / persists across signup-source and account states,
    including a slow-backend case). Onboarding is disabled in the test build by
    default; the specs opt in via a test-only override.

Depends on the backend agent_network_only setting (netbirdio/netbird#6736).

Note: pkgsDownloadUrl still reads the deployment config flag for the RC
installer-channel suffix (plain utility, no hook context), so account-marked
accounts get stable installers — flagged for a follow-up if RC is desired there.

Documentation

Select exactly one:

  • I added/updated documentation for this change
  • Documentation is not needed for this change (explain why)

The focused dashboard view and its Settings opt-out are documented in the docs
PR below.

Docs PR URL (required if "docs added" is checked)

Paste the PR link from https://github.com/netbirdio/docs here:

netbirdio/docs#848

E2E tests

Optional: override the image tags used by the Playwright e2e workflow.
Defaults to main when omitted.

management-cloud-tag: main
reverse-proxy-tag: main

Summary by CodeRabbit

  • New Features

    • Added an Agent Network–focused view toggle in client settings.
    • Added signup-context detection to preserve Agent Network intent through redirects.
  • Improvements

    • Agent Network routes, navigation, selectors, and onboarding now adapt to account mode and loading state.
    • Agent Network-only accounts see focused navigation and an alternate onboarding flow; non-eligible states hide the route tree.
    • Agent Network API requests are gated based on mode and permissions.
  • Tests

    • Added end-to-end coverage for the focused view behavior.

Store the source query parameter into localStorage on app load so it
survives the OIDC redirect, and add the agent_network_only account
setting to the Account interface.
Add useAgentNetworkMode, which combines the deployment config flags
with the account-level agent_network_only setting, and swap the UI
gating call sites (navigation, route guard, control center, flow
selector, providers provider, usage overview) to it. The agent-network
route guard now waits for the account to load before calling notFound
so accounts enabled via settings don't get a redirect flash.
Once the logged-in account is available, apply the stored netbird.ai
signup source: new accounts (signup form still pending) are updated
with agent_network_only via PUT /accounts/{id}, while stale flags from
existing accounts are discarded. The flag is only cleared after a
successful write so failures retry on the next session.
Expose the agent_network_only account setting in the Clients settings
tab so users can leave (or re-enter) the focused view. Shown when the
Agent Network surface is available for the account or deployment.
@coderabbitai

coderabbitai Bot commented Jul 12, 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

Agent Network mode now incorporates account-level settings through a shared hook. The mode controls route access, API fetching, navigation, onboarding, upgrade links, signup initialization, and a new settings toggle.

Changes

Agent Network mode

Layer / File(s) Summary
Mode hook and account shape
src/modules/agent-network/useAgentNetworkMode.ts, src/interfaces/Account.ts
Adds account-backed only, enabled, and loading state through useAgentNetworkMode, including signup-source detection and the corresponding account setting type.
Signup-source account initialization
src/hooks/useSignupSource.ts, src/layouts/AppLayout.tsx, src/cloud/contexts/NetBirdCloudProvider.tsx
Captures the netbird.ai signup source across redirects and applies agent_network_only to eligible accounts once.
Route and data gating
src/app/(dashboard)/agent-network/layout.tsx, src/app/(dashboard)/control-center/page.tsx, src/modules/agent-network/*
Uses hook-derived mode state for route rendering and Agent Network request enablement.
Navigation and mode-dependent surfaces
src/layouts/Navigation.tsx, src/modules/control-center/FlowSelector.tsx, src/modules/onboarding/OnboardingProvider.tsx, src/modules/billing/trial/TrialOrUpgradeButton.tsx
Updates navigation visibility, control-center tabs, onboarding selection, and upgrade URLs to use the shared mode hook.
Account focused-view setting
src/modules/settings/ClientSettingsTab.tsx
Adds a permission-gated toggle that persists and revalidates the account’s agent_network_only setting.
Focused-view end-to-end validation
e2e/tests/agent-network-focused-view.spec.ts
Adds Playwright coverage for focused navigation, route access, opt-out behavior, signup persistence, and settings visibility.

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

Sequence Diagram(s)

sequenceDiagram
  participant AppLayout
  participant BrowserStorage
  participant NetBirdCloudProvider
  participant AccountsAPI
  AppLayout->>BrowserStorage: store signup_source=netbird.ai
  NetBirdCloudProvider->>BrowserStorage: read signup source
  NetBirdCloudProvider->>AccountsAPI: update agent_network_only
  AccountsAPI-->>NetBirdCloudProvider: account response
  NetBirdCloudProvider->>BrowserStorage: remove signup source
Loading

Suggested reviewers: braginini

Poem

I’m a rabbit with a focused view,
Toggling networks with a hop and two.
Hooks guide the paths through cloud and gate,
Signup seeds the account state.
Navigation blooms where agents play—
Thump, thump, shipped today!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% 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
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 matches the main change: focusing the dashboard on Agent Network for netbird.ai signups.
Description check ✅ Passed The description largely follows the template and includes docs and E2E sections, but the issue ticket number and link are not filled in.
✨ 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 feature/agent-network-source-onboarding

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.

@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

🧹 Nitpick comments (1)
src/layouts/Navigation.tsx (1)

179-233: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Extract the repeated agentNetworkEnabled && permission?.services?.read condition.

The same expression is duplicated across the parent item and all 4 children. Extracting it avoids future edits accidentally diverging one occurrence from the rest.

♻️ Proposed refactor
+                {(() => {
+                  const canAccessAgentNetwork =
+                    agentNetworkEnabled && !!permission?.services?.read;
+                  return (
                 <SidebarItem
                   icon={<AgentNetworkIcon size={16} />}
                   ...
-                  visible={agentNetworkEnabled && permission?.services?.read}
+                  visible={canAccessAgentNetwork}
                 >
                   <SidebarItem
                     label="Providers"
                     ...
-                    visible={agentNetworkEnabled && permission?.services?.read}
+                    visible={canAccessAgentNetwork}
                   />
                   {/* ...same for Policies / Usage & Logs / Configuration */}
                 </SidebarItem>
+                  );
+                })()}

(Or, simpler, just define const canAccessAgentNetwork = agentNetworkEnabled && !!permission?.services?.read; near the top of the component alongside agentNetworkOnly/agentNetworkEnabled and reuse it in all 5 places.)

🤖 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 `@src/layouts/Navigation.tsx` around lines 179 - 233, In the Navigation
component, extract the repeated agentNetworkEnabled &&
permission?.services?.read expression into a shared canAccessAgentNetwork value
near agentNetworkOnly and agentNetworkEnabled, then use that value for the Agent
Network parent and all four child SidebarItem visible props.
🤖 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/cloud/contexts/NetBirdCloudProvider.tsx`:
- Around line 54-88: The signup-source effect in NetBirdCloudProvider currently
applies agent_network_only asynchronously, allowing the regular onboarding UI to
flash before revalidation. Track whether the AGENT_NETWORK_SIGNUP_SOURCE is
being consumed and gate OnboardingProvider’s showOnboarding/rendering until
accountRequest settles or the localStorage key is removed, while preserving
normal onboarding behavior for unrelated accounts and completed or
already-configured signups.

---

Nitpick comments:
In `@src/layouts/Navigation.tsx`:
- Around line 179-233: In the Navigation component, extract the repeated
agentNetworkEnabled && permission?.services?.read expression into a shared
canAccessAgentNetwork value near agentNetworkOnly and agentNetworkEnabled, then
use that value for the Agent Network parent and all four child SidebarItem
visible props.
🪄 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: CHILL

Plan: Pro

Run ID: 25446e7c-3a47-4299-ae57-b2165859de11

📥 Commits

Reviewing files that changed from the base of the PR and between 58d1035 and fb409b7.

📒 Files selected for processing (14)
  • src/app/(dashboard)/agent-network/layout.tsx
  • src/app/(dashboard)/control-center/page.tsx
  • src/cloud/contexts/NetBirdCloudProvider.tsx
  • src/hooks/useSignupSource.ts
  • src/interfaces/Account.ts
  • src/layouts/AppLayout.tsx
  • src/layouts/Navigation.tsx
  • src/modules/agent-network/AIProvidersProvider.tsx
  • src/modules/agent-network/AgentOverviewPanel.tsx
  • src/modules/agent-network/useAgentNetworkMode.ts
  • src/modules/billing/trial/TrialOrUpgradeButton.tsx
  • src/modules/control-center/FlowSelector.tsx
  • src/modules/onboarding/OnboardingProvider.tsx
  • src/modules/settings/ClientSettingsTab.tsx

Comment thread src/cloud/contexts/NetBirdCloudProvider.tsx
Prevents the regular onboarding from flashing before agent_network_only is
persisted: while a new account still carries the netbird.ai signup source and
is unmarked, the focused view applies immediately. Gated on signup_form_pending
so an existing user's stale source flag never flips the view.

@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/modules/agent-network/useAgentNetworkMode.ts`:
- Around line 16-18: Update isAgentNetworkSignupPending and the related
agent-network mode decision around isAgentNetworkOnly so an explicit
account.settings.agent_network_only === false always opts out. Use nullish
fallback semantics for optional settings, and apply signup-pending optimism only
when agent_network_only is absent, without allowing deployment configuration to
override the explicit false value.
🪄 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: CHILL

Plan: Pro

Run ID: 58b5e0dd-cd82-41c5-a542-6f6a662f650d

📥 Commits

Reviewing files that changed from the base of the PR and between fb409b7 and b280848.

📒 Files selected for processing (1)
  • src/modules/agent-network/useAgentNetworkMode.ts

Comment thread src/modules/agent-network/useAgentNetworkMode.ts Outdated
Use nullish fallback so an explicit account setting (true or false) always
wins: a user can disable the focused view even when the deployment config
enables it, and the signup-pending optimism only applies when the setting is
absent, never overriding an explicit false.

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

🧹 Nitpick comments (2)
e2e/tests/agent-network-focused-view.spec.ts (2)

140-140: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use visitByNavigation instead of direct click for sidebar navigation.

Line 140 clicks the "Agent Network" sidebar item directly via navItem(page, "Agent Network").click(). Use visitByNavigation(page, "Agent Network") to click sidebar items for navigation, per the test conventions.

As per coding guidelines: "Use visitByNavigation(page, navText) to click sidebar items for navigation instead of direct element selection."

♻️ Proposed fix
-      await navItem(page, "Agent Network").click();
+      await visitByNavigation(page, "Agent Network");
🤖 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 `@e2e/tests/agent-network-focused-view.spec.ts` at line 140, Replace the direct
sidebar click in the Agent Network navigation flow with visitByNavigation(page,
"Agent Network"), preserving the existing navigation behavior and following the
established test convention.

Source: Coding guidelines


198-200: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use page.waitForResponse() instead of expect.poll for waiting on API responses.

The test polls captured.putBody to detect the PUT request. The coding guidelines specify using page.waitForResponse() with timeout and method/URL matching. Since the PUT is triggered by an app effect (not a user action in the test), set up the listener before or immediately after loginToApp to avoid missing the response.

As per coding guidelines: "Use page.waitForResponse() with timeout and method/URL matching to wait for specific API responses before assertions."

♻️ Proposed fix
-      // The signup source is persisted as the account setting.
-      await expect
-        .poll(() => captured.putBody?.settings?.agent_network_only)
-        .toBe(true);
+      // The signup source is persisted as the account setting.
+      const putResponse = await page.waitForResponse(
+        (response) =>
+          response.url().includes("/api/accounts/") &&
+          response.request().method() === "PUT",
+        { timeout: 15000 },
+      );
+      const putBody = await putResponse.request().postDataJSON();
+      expect(putBody?.settings?.agent_network_only).toBe(true);
🤖 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 `@e2e/tests/agent-network-focused-view.spec.ts` around lines 198 - 200, Replace
the expect.poll assertion on captured.putBody.settings.agent_network_only with
page.waitForResponse(), configuring a timeout and matching the PUT method and
expected API URL. Register the response listener before or immediately after
loginToApp so the app-triggered request cannot be missed, then assert the
response body or captured request data confirms agent_network_only is true.

Source: Coding guidelines

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

Nitpick comments:
In `@e2e/tests/agent-network-focused-view.spec.ts`:
- Line 140: Replace the direct sidebar click in the Agent Network navigation
flow with visitByNavigation(page, "Agent Network"), preserving the existing
navigation behavior and following the established test convention.
- Around line 198-200: Replace the expect.poll assertion on
captured.putBody.settings.agent_network_only with page.waitForResponse(),
configuring a timeout and matching the PUT method and expected API URL. Register
the response listener before or immediately after loginToApp so the
app-triggered request cannot be missed, then assert the response body or
captured request data confirms agent_network_only is true.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8a423421-ba06-4c67-9dde-3a86144aa034

📥 Commits

Reviewing files that changed from the base of the PR and between 55f2847 and cc7b811.

📒 Files selected for processing (1)
  • e2e/tests/agent-network-focused-view.spec.ts

Await the /accounts revalidation before clearing the netbird.ai signup source
key. Clearing it first left a window where neither the source-pending optimism
nor the persisted agent_network_only setting held, so the focused view flipped
off for a beat and tore down the onboarding form exactly as the enablement
toast appeared.
The agent-network onboarding signup-form step was gated self-hosted-only, so
cloud netbird.ai signups skipped it. Drive it off signup_form_pending on both
cloud and self-hosted so those users fill the form and then continue through
the agent-network onboarding flow.
…m flash

account can load before useAgentNetworkMode's own /accounts fetch settles,
which briefly rendered the regular onboarding form and then switched to the
Agent Network flow. Hold onboarding while the mode is loading so the user only
ever sees the correct form.
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Note

Unit test generation is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.


Generating unit tests... This may take up to 20 minutes.

…lashes

Reading the netbird.ai signup source synchronously lets onboarding commit to
the Agent Network form on the first render, independent of when the account
setting or agent-network mode data settles. The regular form is no longer shown
to netbird.ai arrivals while the backend catches up.
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Request timed out after 900000ms (requestId=96918499-15ad-4cb7-a9c8-2090e792b7a8)

Adds a test-only override to render onboarding in the test build, testids on
both onboarding forms, and a spec validating which form shows first and which
persists: netbird.ai signup shows the Agent Network form (never the regular
one, even under a slow backend), a plain cloud account shows the regular form,
and an agent_network_only account shows the Agent Network form.
@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Note

Unit test generation is a beta feature. Expect some limitations and changes as we gather feedback and continue to improve it.


Generating unit tests... This may take up to 20 minutes.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026

Copy link
Copy Markdown
Contributor

Request timed out after 900000ms (requestId=03d4487e-69a4-4b84-b1ab-45d0979f3050)

@braginini braginini self-requested a review July 12, 2026 18:55
@mlsmaycon mlsmaycon merged commit a266fff into main Jul 12, 2026
8 checks passed
@mlsmaycon mlsmaycon deleted the feature/agent-network-source-onboarding branch July 12, 2026 19:16
ocoj added a commit to ocoj/dashboard that referenced this pull request Jul 13, 2026
Upstream features preserved:
- Agent Network (netbirdio#684, netbirdio#708)
- Lazy Connections (netbirdio#706)
- New Traffic Filters (netbirdio#704)
- Cluster one-click deploy (netbirdio#707)
- etc.

i18n preserved:
- All zh.ts/en.ts keys intact
- Control-center, VersionInfo, Navigation translations
- Translation framework (next-intl) retained

Resolved: Navigation t() definition, PeersTable types
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.

2 participants