Skip to content

Bootstrap Agent Network settings via the explicit POST - #746

Merged
bison merged 4 commits into
mainfrom
feat/agent-network-settings-bootstrap
Aug 11, 2026
Merged

Bootstrap Agent Network settings via the explicit POST#746
bison merged 4 commits into
mainfrom
feat/agent-network-settings-bootstrap

Conversation

@bison

@bison bison commented Aug 7, 2026

Copy link
Copy Markdown
Member

Important

Depends on netbirdio/netbird#7085 (management: rework Agent Network endpoint identity and settings bootstrap). Draft until that merges — against a management build without it, the settings POST this introduces does not exist.

Adopts the new Agent Network settings contract:

  • The management API replaced the implicit settings bootstrap — a bootstrap_cluster hint on the first provider create — with an explicit POST /agent-network/settings carrying the proxy cluster address. The settings response now carries endpoint + proxy_address + dedicated instead of cluster + subdomain.
  • The provider wizard keeps its UX (auto-picking a validated cluster, gating the first create on having one) but now bootstraps the settings row with the explicit POST right before the first provider create. A bootstrap failure keeps the wizard open and surfaces the error — previously a failed bootstrap was swallowed server-side and the account silently ended up with a provider but no endpoint. A 409 (concurrent bootstrap won) is treated as success, since the row exists either way.
  • Types updated accordingly; bootstrapAgentNetworkSettings is exposed on the providers context. The onboarding provider step reuses the same wizard, so it is covered by the same change.

Without this, the dashboard against a new management silently stops bootstrapping accounts: provider create succeeds (the old hint is an ignored unknown field), but no endpoint is ever assigned.

Verified manually end to end against a local management running netbirdio/netbird#7085 (labeled bootstrap through the wizard, endpoint rendered, second create skips the bootstrap, failure path keeps the wizard open).

Issue ticket number and link

Internal (NetBird team) change; ticket to be linked alongside the management PR before this leaves draft.

Documentation

Select exactly one:

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

Docs for the changed settings API are being handled with the management PR (netbirdio/netbird#7085); nothing dashboard-specific beyond that.

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

Note: the agent-network e2e flow cannot pass against main images until netbirdio/netbird#7085 merges and images are rebuilt — the settings POST doesn't exist there yet.

Summary by CodeRabbit

  • New Features

    • Added explicit Agent Network setup before creating the first AI provider.
    • The selected proxy address is applied during setup.
    • Settings can be refreshed and retried when setup is incomplete.
  • Bug Fixes

    • Provider creation now stops safely if setup fails.
    • Concurrent setup requests are handled without blocking creation.
    • Uninitialized settings are handled consistently across empty and unavailable responses.
    • Service-user updates now reliably save changes and refresh displayed lists.

@CLAassistant

CLAassistant commented Aug 7, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai

coderabbitai Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 31283d55-99c7-40bf-9b88-9ec4dc83857b

📥 Commits

Reviewing files that changed from the base of the PR and between f7255c5 and 8512548.

📒 Files selected for processing (3)
  • e2e/tests/agent-network-kimi-provider.spec.ts
  • e2e/tests/agent-network-settings-shapes.spec.ts
  • e2e/tests/team-service-users.spec.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • e2e/tests/agent-network-settings-shapes.spec.ts
  • e2e/tests/agent-network-kimi-provider.spec.ts
  • e2e/tests/team-service-users.spec.ts

📝 Walkthrough

Walkthrough

The PR adds explicit account-level Agent Network settings bootstrap before first provider creation. It updates settings models and requests, handles uninitialized and concurrent bootstrap states, and strengthens Agent Network and service-user E2E coverage.

Changes

Agent Network settings bootstrap

Layer / File(s) Summary
Settings contracts and request mapping
src/modules/agent-network/AIProvidersProvider.tsx
Settings use endpoint, proxy_address, and dedicated. Provider requests no longer include bootstrap cluster fields. PUT requests include immutable identity fields.
Bootstrap and update operations
src/modules/agent-network/AIProvidersProvider.tsx
The context adds bootstrapAgentNetworkSettings. Bootstrap handles failures and concurrent 409 responses. Updates reject uninitialized settings.
First provider creation integration
src/modules/agent-network/AIProviderModal.tsx
The modal bootstraps settings with the selected cluster before creating the first provider. Failed bootstrap keeps the modal open.
Agent Network E2E coverage
e2e/helpers/api.ts, e2e/tests/agent-network-kimi-provider.spec.ts, e2e/tests/agent-network-settings-shapes.spec.ts
E2E tests detect endpoint support, validate bootstrap failure handling, and use the new settings response shape.

Service-user E2E navigation

Layer / File(s) Summary
Service-user navigation and persistence helpers
e2e/tests/team-service-users.spec.ts
Service-user tests use typed helpers that verify navigation, list readiness, role selection, and successful user-specific updates.

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

Sequence Diagram(s)

sequenceDiagram
  participant AIProviderModal
  participant AIProvidersProvider
  participant AgentNetworkSettingsAPI
  AIProviderModal->>AIProvidersProvider: bootstrapAgentNetworkSettings(proxyAddress)
  AIProvidersProvider->>AgentNetworkSettingsAPI: create settings with proxy_address
  AgentNetworkSettingsAPI-->>AIProvidersProvider: success or 409
  AIProvidersProvider->>AgentNetworkSettingsAPI: refresh settings after 409
  AIProvidersProvider-->>AIProviderModal: bootstrap result
  AIProviderModal->>AIProvidersProvider: addProvider()
Loading

Possibly related PRs

Suggested reviewers: braginini

Poem

A rabbit checks the settings gate,
Then helps the provider start its state.
A failed bootstrap keeps the form in view,
While 409 confirms what others do.
Typed tests guide each service-user queue.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% 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
Title check ✅ Passed The title clearly identifies the main change: bootstrapping Agent Network settings through an explicit POST request.
Description check ✅ Passed The description explains the change, dependency, documentation decision, testing status, and E2E constraints; only the issue link remains pending.
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/agent-network-settings-bootstrap

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

e2e/tests/agent-network-kimi-provider.spec.ts

Oops! Something went wrong! :(

ESLint: 9.39.5

TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'configs' -> object with constructor 'Object'
| property 'flat' -> object with constructor 'Object'
| ...
| property 'plugins' -> object with constructor 'Object'
--- property 'react' closes the circle
Referenced from: /.eslintrc.json
at JSON.stringify ()
at /node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2255:45
at Array.map ()
at ConfigValidator.formatErrors (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2246:23)
at ConfigValidator.validateConfigSchema (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2277:84)
at ConfigArrayFactory._normalizeConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3123:19)
at ConfigArrayFactory._loadConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3088:21)
at ConfigArrayFactory._loadExtendedShareableConfig (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3393:21)
at ConfigArrayFactory._loadExtends (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3261:25)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3199:25)
(node:2) ESLintRCWarning: You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.
(Use node --trace-warnings ... to show where the warning was created)

e2e/tests/agent-network-settings-shapes.spec.ts

Oops! Something went wrong! :(

ESLint: 9.39.5

TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'configs' -> object with constructor 'Object'
| property 'flat' -> object with constructor 'Object'
| ...
| property 'plugins' -> object with constructor 'Object'
--- property 'react' closes the circle
Referenced from: /.eslintrc.json
at JSON.stringify ()
at /node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2255:45
at Array.map ()
at ConfigValidator.formatErrors (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2246:23)
at ConfigValidator.validateConfigSchema (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2277:84)
at ConfigArrayFactory._normalizeConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3123:19)
at ConfigArrayFactory._loadConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3088:21)
at ConfigArrayFactory._loadExtendedShareableConfig (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3393:21)
at ConfigArrayFactory._loadExtends (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3261:25)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3199:25)
(node:2) ESLintRCWarning: You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.
(Use node --trace-warnings ... to show where the warning was created)

e2e/tests/team-service-users.spec.ts

Oops! Something went wrong! :(

ESLint: 9.39.5

TypeError: Converting circular structure to JSON
--> starting at object with constructor 'Object'
| property 'configs' -> object with constructor 'Object'
| property 'flat' -> object with constructor 'Object'
| ...
| property 'plugins' -> object with constructor 'Object'
--- property 'react' closes the circle
Referenced from: /.eslintrc.json
at JSON.stringify ()
at /node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2255:45
at Array.map ()
at ConfigValidator.formatErrors (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2246:23)
at ConfigValidator.validateConfigSchema (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2277:84)
at ConfigArrayFactory._normalizeConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3123:19)
at ConfigArrayFactory._loadConfigData (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3088:21)
at ConfigArrayFactory._loadExtendedShareableConfig (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3393:21)
at ConfigArrayFactory._loadExtends (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3261:25)
at ConfigArrayFactory._normalizeObjectConfigDataBody (/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:3199:25)
(node:2) ESLintRCWarning: You are using an eslintrc configuration file, which is deprecated and support will be removed in v10.0.0. Please migrate to an eslint.config.js file. See https://eslint.org/docs/latest/use/configure/migration-guide for details. An eslintrc configuration file is used because you have the ESLINT_USE_FLAT_CONFIG environment variable set to false. If you want to use an eslint.config.js file, remove the environment variable. If you want to find the location of the eslintrc configuration file, use the --debug flag.
(Use node --trace-warnings ... to show where the warning was created)


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.

mlsmaycon
mlsmaycon previously approved these changes Aug 8, 2026
bison and others added 2 commits August 10, 2026 19:07
The management API replaced the implicit settings bootstrap (a
bootstrap_cluster hint on the first provider create) with an explicit
POST /agent-network/settings carrying the proxy cluster address; the
settings response now carries endpoint + proxy_address + dedicated
instead of cluster + subdomain, and the endpoint is assigned as a
server-allocated label beneath the proxy address.

The wizard keeps its UX — auto-picking a validated cluster and gating
the first create on having one — but now bootstraps the settings row
with an explicit POST right before the first provider create. A
bootstrap failure keeps the wizard open and surfaces the error instead
of being swallowed server-side, and a 409 (concurrent bootstrap won) is
treated as success since the row exists either way.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The settings PUT now follows the REST API's full-replace convention:
every field is required, including endpoint and proxy_address. The
backend compares the identity fields against the stored row and rejects
a mismatch with 422 instead of leaving them out of the schema, so the
update path now echoes the loaded settings' identity verbatim — stored
values only, never user input, which keeps the rejection unreachable
from the UI. A save before the settings row exists fails fast with a
notification; the backend would 404 that PUT anyway.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@bison
bison force-pushed the feat/agent-network-settings-bootstrap branch from 4e47121 to b59d7d7 Compare August 10, 2026 17:07
@bison
bison marked this pull request as ready for review August 10, 2026 17:08
mlsmaycon
mlsmaycon previously approved these changes Aug 10, 2026
…bootstrap on old backends

Two unrelated Playwright failures on this branch.

The service-users suite reverted its own change and then blamed the UI.
Returning to the list by clicking the nav entry resolves while the
client-side navigation is still in flight, so the next test's row click
was computed against the page being left behind and landed on the wrong
row. Both role PUTs went to the regular user, the second undoing the
first, and the assertions two steps later failed on a list that was
telling the truth. Nothing checked either the target or the status of the
PUT, so the mis-edit passed silently.

Land on the list deterministically, confirm the user page really belongs
to the user being opened before editing it, verify the role pick landed,
and pin the PUT to the open user's id with a status assertion — so a
mis-click fails where it happens instead of corrupting account state.

The Kimi suite timed out at 30s because the first provider create now
bootstraps the settings row first, and POST /agent-network/settings does
not exist before netbirdio/netbird#7085. The wizard never got to the
provider create, and the wait for it hung. Probe the endpoint off the
settings GET shape and skip, as the suite already does for a catalog
without kimi_api, plus race a rejected bootstrap so the status is
reported rather than a bare timeout.

Also update the settings wire-shape fixtures to the new contract; they
still described cluster + subdomain and only passed by accident.

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

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

🧹 Nitpick comments (1)
e2e/tests/team-service-users.spec.ts (1)

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

Use data-testid selectors for navigation and row selection.

returnToServiceUserList selects the breadcrumb with getByRole. openServiceUser selects a table row with locator("tr"). Replace both interactive selectors with page.getByTestId() selectors. Add the required test IDs to the UI if they do not exist.

As per coding guidelines, use data-testid selectors via page.getByTestId() for element selection in Playwright tests.

🤖 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/team-service-users.spec.ts` around lines 101 - 125, Replace the
role-based navigation selector in returnToServiceUserList and the generic row
locator in openServiceUser with page.getByTestId() selectors. Add the
corresponding data-testid attributes to the Service Users navigation link and
user rows if they are not already present, while preserving the existing URL and
visibility checks.

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.

Inline comments:
In `@e2e/tests/agent-network-kimi-provider.spec.ts`:
- Around line 146-149: Replace the role-based selector for the “Connect
Provider” action in this test with page.getByTestId() using the component’s
existing test ID; if none exists, add an appropriate kebab-case data-testid to
the button and target it from the test.
- Around line 129-145: Update the bootstrap failure response predicate in the
provider creation race so HTTP 409 responses are excluded from failure matching,
while continuing to reject other non-2xx responses. Preserve the existing
timeout and pending-promise behavior for responses that do not match.

In `@e2e/tests/agent-network-settings-shapes.spec.ts`:
- Around line 26-27: Correct the comment describing UNBOOTSTRAPPED_DEFAULTS to
identify the fixture as unbootstrapped settings, while retaining the notes about
present values, empty endpoint/proxy_address, and absent timestamps.

---

Nitpick comments:
In `@e2e/tests/team-service-users.spec.ts`:
- Around line 101-125: Replace the role-based navigation selector in
returnToServiceUserList and the generic row locator in openServiceUser with
page.getByTestId() selectors. Add the corresponding data-testid attributes to
the Service Users navigation link and user rows if they are not already present,
while preserving the existing URL and visibility checks.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: dbd4f8f6-526f-45bb-858b-143911fc2663

📥 Commits

Reviewing files that changed from the base of the PR and between b59d7d7 and f7255c5.

📒 Files selected for processing (4)
  • e2e/helpers/api.ts
  • e2e/tests/agent-network-kimi-provider.spec.ts
  • e2e/tests/agent-network-settings-shapes.spec.ts
  • e2e/tests/team-service-users.spec.ts

Comment thread e2e/tests/agent-network-kimi-provider.spec.ts
Comment thread e2e/tests/agent-network-kimi-provider.spec.ts
Comment thread e2e/tests/agent-network-settings-shapes.spec.ts Outdated
…ser specs

Do not treat a 409 from the settings bootstrap as a failure in the Kimi
provider race. The wizard accepts it — a concurrent bootstrap won, so the
row exists — and goes on to create the provider, so matching it would fail
a run that was about to succeed. Other agent-network suites run in the
second worker against the same account, which is exactly where that race
comes from.

Select the breadcrumb by its existing breadcrumb-item test id rather than
by role, per the e2e selector guidance.

Reflow the unbootstrapped fixture comment: "before the account is
bootstrapped" wrapped across lines and read as though the fixture were
the bootstrapped one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@bison
bison merged commit a92816b into main Aug 11, 2026
7 checks passed
@bison
bison deleted the feat/agent-network-settings-bootstrap branch August 11, 2026 09:32
@fosskar fosskar Bot mentioned this pull request Aug 14, 2026
ocoj pushed a commit to ocoj/dashboard that referenced this pull request Aug 16, 2026
Adopts the new Agent Network settings contract:

- The management API replaced the implicit settings bootstrap — a
  `bootstrap_cluster` hint on the first provider create — with an
  explicit POST /agent-network/settings carrying the proxy cluster
  address. The settings response now carries endpoint +
  proxy_address + dedicated instead of cluster + subdomain.

- The provider wizard keeps its UX (auto-picking a validated cluster,
  gating the first create on having one) but now bootstraps the
  settings row with the explicit POST right before the first provider
  create. A bootstrap failure keeps the wizard open and surfaces the
  error — previously a failed bootstrap was swallowed server-side and
  the account silently ended up with a provider but no endpoint. A 409
  (concurrent bootstrap won) is treated as success, since the row
  exists either way.

- Types updated accordingly; bootstrapAgentNetworkSettings is exposed
  on the providers context. The onboarding provider step reuses the
  same wizard, so it is covered by the same change.

Without this, the dashboard against a new management silently stops
bootstrapping accounts: provider create succeeds (the old hint is an
ignored unknown field), but no endpoint is ever assigned.
TechHutTV pushed a commit that referenced this pull request Aug 27, 2026
Adopts the new Agent Network settings contract:

- The management API replaced the implicit settings bootstrap — a
  `bootstrap_cluster` hint on the first provider create — with an
  explicit POST /agent-network/settings carrying the proxy cluster
  address. The settings response now carries endpoint +
  proxy_address + dedicated instead of cluster + subdomain.

- The provider wizard keeps its UX (auto-picking a validated cluster,
  gating the first create on having one) but now bootstraps the
  settings row with the explicit POST right before the first provider
  create. A bootstrap failure keeps the wizard open and surfaces the
  error — previously a failed bootstrap was swallowed server-side and
  the account silently ended up with a provider but no endpoint. A 409
  (concurrent bootstrap won) is treated as success, since the row
  exists either way.

- Types updated accordingly; bootstrapAgentNetworkSettings is exposed
  on the providers context. The onboarding provider step reuses the
  same wizard, so it is covered by the same change.

Without this, the dashboard against a new management silently stops
bootstrapping accounts: provider create succeeds (the old hint is an
ignored unknown field), but no endpoint is ever assigned.
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.

3 participants