Skip to content

chore: remove agents experiment flag and mark feature as beta#24432

Merged
deansheather merged 11 commits into
mainfrom
remove-agents-experiment-flag
Apr 30, 2026
Merged

chore: remove agents experiment flag and mark feature as beta#24432
deansheather merged 11 commits into
mainfrom
remove-agents-experiment-flag

Conversation

@deansheather

@deansheather deansheather commented Apr 16, 2026

Copy link
Copy Markdown
Member

Remove the ExperimentAgents feature flag so the Agents feature is
always available without requiring --experiments=agents. The feature
is now in beta.

Existing deployments that still pass --experiments=agents will get a
harmless "ignoring unknown experiment" warning on startup.

Changes

Backend:

  • Remove RequireExperimentWithDevBypass middleware from chat and MCP server routes
  • Always include AgentsAccessRole in assignable site roles (later refactored to org-scoped on main; rebase keeps that)
  • Always set AgentsTabVisible = true, then drop the entire dead AgentsTabVisible metadata pipeline (Go htmlState field, populateHTMLState goroutine, HTML meta tag, useEmbeddedMetadata registration, mock); no production consumer reads it. AgentsNavItem already gates on permissions.createChat.
  • Make blob: CSP img-src addition unconditional
  • Remove ExperimentAgents constant, DisplayName case, and ExperimentsKnown entry

CLI:

  • Graduate the agents TUI from coder exp agents to coder agents (moved from AGPLExperimental() to CoreSubcommands())
  • Drop the agent alias so it does not collide with the hidden workspace-agent command
  • Rename implementation files cli/exp_agents_*.go -> cli/agents_*.go and internal identifiers (expChatsTUIModel -> chatsTUIModel, newExpChatsTUIModel -> newChatsTUIModel, setupExpAgentsBackend -> setupAgentsBackend, startExpAgentsSession -> startAgentsSession, expAgentsPtr -> agentsPtr, expAgentsSession -> agentsSession, TestExpAgents* -> TestAgents*). expClient (the *codersdk.ExperimentalClient local) is kept; coderd/exp_chats*.go and other still-experimental cli/exp_*.go commands are intentionally untouched.

Frontend:

  • Remove experiment check from AgentsNavItem - render when canCreateChat is true
  • Remove agentsEnabled experiment check from WorkspacesPage, then gate chatsByWorkspace on permissions.createChat so users without chat access don't trigger the per-page DB query (Copilot review feedback)
  • Add FeatureStageBadge (beta) next to the Coder logo in the Agents sidebar (desktop + mobile)

Docs:

  • Remove experiment flag setup instructions from early-access.md and getting-started.md (and rename early-access.md's "Enable Coder Agents" heading to "Set up Coder Agents", since there is no enablement step left)
  • Update chats-api.md and getting-started.md's Chats API note to say "beta" instead of "experimental"
  • docs/manifest.json: drop "experimental" from the Chats API sidebar description
  • make gen regenerated docs/reference/cli/agents.md and the CLI index
  • scripts/check_emdash.sh: exclude cli/testdata/*.golden and enterprise/cli/testdata/*.golden from the new repo-wide emdash lint, since serpent emits emdash borders in every generated --help golden file

Tests:

  • Remove ExperimentAgents setup from all test files (14 occurrences across 7 files)
  • Update stale "with the agents experiment" comments in coderd/x/chatd/integration_test.go and coderd/mcp_test.go
image

🤖 Generated by Coder Agents

@deansheather deansheather force-pushed the remove-agents-experiment-flag branch 2 times, most recently from 0f034ed to 4a61a18 Compare April 20, 2026 11:32
@deansheather deansheather requested a review from Copilot April 20, 2026 11:33
@deansheather deansheather marked this pull request as ready for review April 20, 2026 11:33

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

Pull request overview

This PR graduates the Agents feature from an experiment flag to a default (beta) feature across backend routing, CLI surface area, frontend navigation/UX, and documentation, removing all ExperimentAgents gating while keeping the /api/experimental/* API paths.

Changes:

  • Removed ExperimentAgents gating across backend routes, SDK experiment definitions, and frontend feature checks; made Agents visibility/roles unconditional.
  • Promoted the Agents CLI TUI from coder exp agents to coder agents and regenerated CLI/docs artifacts accordingly.
  • Updated docs and UI to reflect “beta” status (including a beta badge in the Agents sidebar/header) and removed “enable experiment flag” instructions.

Reviewed changes

Copilot reviewed 36 out of 43 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
site/src/pages/WorkspacesPage/WorkspacesPage.tsx Removes agents experiment gating for the chats-by-workspace query on Workspaces page.
site/src/pages/AgentsPage/components/Sidebar/AgentsSidebar.tsx Adds beta stage badge next to the logo in the Agents sidebar.
site/src/pages/AgentsPage/components/Sidebar/AgentsSidebar.test.tsx Wraps sidebar tests with TooltipProvider to support new tooltip-using badge.
site/src/pages/AgentsPage/components/AgentPageHeader.tsx Adds beta stage badge next to the logo in the mobile Agents header.
site/src/modules/dashboard/Navbar/NavbarView.tsx Removes experiment check from AgentsNavItem; renders based on canCreateChat only.
site/src/modules/dashboard/Navbar/NavbarView.stories.tsx Removes storybook experiment parameter now that Agents is not gated.
site/src/api/typesGenerated.ts Regenerates types to remove "agents" from Experiment union/list.
site/site.go Sets AgentsTabVisible HTML state to true unconditionally.
plans/CODAGT-156-remove-experimental-flags.md Adds implementation plan/verification checklist for removing Agents experiment flag.
enterprise/coderd/roles_test.go Removes Agents experiment setup from enterprise roles test.
enterprise/coderd/exp_chats_test.go Removes Agents experiment setup from enterprise chats tests.
docs/reference/cli/index.md Adds agents command to generated CLI index.
docs/reference/cli/agents.md Adds generated reference doc for coder agents.
docs/reference/api/schemas.md Updates generated API schema docs to remove agents from experiment enum values.
docs/manifest.json Removes “experimental” phrasing from Chats API description in docs manifest.
docs/ai-coder/agents/getting-started.md Removes experiment enablement step; renumbers setup steps.
docs/ai-coder/agents/early-access.md Removes --experiments=agents instructions; notes Agents available by default.
docs/ai-coder/agents/chats-api.md Updates Chats API note from experimental-gated to beta.
codersdk/deployment.go Removes ExperimentAgents constant and related display/known-experiments entries.
coderd/x/chatd/integration_test.go Removes Agents experiment setup from chatd integration tests.
coderd/x/chatd/chatd_test.go Removes Agents experiment setup from chatd tests.
coderd/roles.go Always includes AgentsAccessRole in assignable site roles.
coderd/mcp_test.go Removes Agents experiment setup and updates comments in MCP tests.
coderd/exp_chats_test.go Removes Agents experiment setup from chats tests.
coderd/coderd.go Removes experiment middleware from chat/MCP routes; makes blob: img-src CSP addition unconditional.
coderd/apidoc/swagger.json Regenerates Swagger JSON to remove agents experiment enum/docs.
coderd/apidoc/docs.go Regenerates embedded Swagger template to remove agents experiment enum/docs.
cli/testdata/coder_agents_--help.golden Adds golden help output for coder agents.
cli/testdata/coder_--help.golden Updates root help golden to include agents command.
cli/root.go Moves agents command into core subcommands (out of experimental).
cli/agents_test.go Renames tests and updates model constructor naming to non-exp.
cli/agents_styles.go Adds shared TUI styles for the promoted agents command.
cli/agents_stream_test.go Adds tests for streaming output consumption helper.
cli/agents_render_test.go Renames render test to non-exp naming.
cli/agents_render.go Adds transcript/tool rendering logic for agents TUI.
cli/agents_model.go Renames the main TUI model from exp-prefixed to stable naming.
cli/agents_list.go Adds chat list UI model (search, expand/collapse, navigation).
cli/agents_helpers.go Adds terminal text sanitization helper.
cli/agents_e2e_test.go Renames E2E tests and updates invocation to coder agents.
cli/agents_e2e_helpers_test.go Updates backend/session helpers for new coder agents command path.
cli/agents_cmds.go Adds tea messages/commands for loading chats, history, tool results, and streaming.
cli/agents_chat.go Adds chat view model (streaming, rendering, tool-call overlays like ask_user_question).
cli/agents.go Promotes command definition to coder agents and removes the agent alias.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 133 to 136
const chatsByWorkspaceQuery = useQuery({
...chatsByWorkspace(workspaceIds),
enabled: agentsEnabled && workspaceIds.length > 0,
enabled: workspaceIds.length > 0,
});

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.

Done in 04fb69d — gated the query on permissions.createChat, matching the existing canCreateChat pattern used elsewhere in the codebase.

deansheather added a commit that referenced this pull request Apr 23, 2026
Address Copilot review feedback on #24432: after dropping the
experiment flag, the Workspaces page was fetching chatsByWorkspace for
every user with workspaces, even users who can't create chats. The
endpoint still runs a DB query + RBAC post-filter and the downstream
UI (AgentsNavItem, chat link icon in the workspaces table) is already
hidden for users without createChat, so the fetch is pure waste for
them.

Gate the useQuery on permissions.createChat, matching the existing
canCreateChat pattern used in Navbar.tsx and AgentCreatePage.tsx.
@deansheather deansheather force-pushed the remove-agents-experiment-flag branch from 4a61a18 to d37c1ee Compare April 23, 2026 07:58
@deansheather

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review coder-agents-review 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.

Clean experiment removal across 46 files. The ExperimentAgents flag is fully excised from Go, TypeScript, docs, and tests, with no orphaned references. The architectural decision to replace the two-layer gate (experiment flag + RBAC) with RBAC-only is sound: the AgentsAccessRole remains the access control mechanism, and the permissions.createChat frontend guard is tighter than the old experiment flag (skips useless API calls for users without the role). The emdash exclusion for golden files is a proactive fix for a pre-existing gap. Commit messages are well-structured.

Severity count: 1 P2, 3 P3, 1 P4, 2 Nit.

The P2 is a docs inconsistency where getting-started.md still says "experimental" while chats-api.md was updated to "beta." The P3s are a stale PR description that contradicts the diff, a stale doc comment on mcpDeploymentValues, and a misleading doc heading.

[DEREM-2] The PR description states: "the implementation files are still named cli/exp_agents_*.go and internal identifiers still use exp prefixes." The diff renames every file and every identifier. Update the description to reflect what was delivered.

"This is the gap between stated intent and actual action." (Mafu-san)

PS. 11 of 17 reviewers independently flagged the AgentsTabVisible metadata pipeline as dead code. The backend goroutine, HTML meta tag, metadata registration, and test mock are all orphaned. The mock still says false while production returns true. This needs a human decision: file a cleanup ticket or accept the dead plumbing.


docs/ai-coder/agents/getting-started.md:247

P2 [DEREM-1] chats-api.md line 4 was updated to say "The Chats API is in beta." This line still reads "The Chats API is experimental and may change without notice." Same API, two maturity labels in the same doc set, authored in the same PR. An operator reading the getting-started guide sees "experimental," clicks through to the Chats API reference, and sees "beta."

Fix: change to match chats-api.md:

> The Chats API is in beta and may change without notice.

(Leorio P2, Mafuuu P3)

🤖

coderd/mcp_test.go:21

P3 [DEREM-3] The comment reads "mcpDeploymentValues returns deployment values with the agents experiment enabled, which is required by the MCP server config endpoints." The function body no longer sets any experiment, and the MCP routes no longer require it. The comment actively contradicts the code.

Fix: rewrite to "mcpDeploymentValues returns deployment values for MCP tests." or inline coderdtest.DeploymentValues(t) at each call site.

(Knov P3, Bisky Nit, Kite Nit)

🤖

coderd/rbac/roles.go:897

Nit [DEREM-7] The comment reads "e.g. when the agents experiment is enabled" but the experiment no longer exists. The caller (coderd/roles.go:47) now includes this role unconditionally.

(Kurapika)

🤖

🤖 This review was automatically generated with Coder Agents.

Comment thread docs/ai-coder/agents/early-access.md Outdated
@@ -42,25 +42,9 @@ redesign.

## Enable Coder Agents

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.

P3 [DEREM-4] The heading says "Enable Coder Agents" but the body says "Coder Agents is available by default. No experiment flags are required." The heading implies there is an enablement procedure; the body says there isn't one. The heading is a vestigial label from when the section had real enablement instructions.

Consider renaming to "Get started with Coder Agents" or "Set up Coder Agents" to match the body.

(Razor P3, Leorio Note)

🤖

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.

DEREM-4: Done in eeb8201 — heading renamed to 'Set up Coder Agents'.

Comment thread site/site.go Outdated
agentsTabVisible = experiments.Enabled(codersdk.ExperimentAgents)
}
data, err := json.Marshal(agentsTabVisible)
data, err := json.Marshal(true)

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.

P4 [DEREM-5] The goroutine marshals a constant true into state.AgentsTabVisible. The HTML template emits it as a meta tag. useEmbeddedMetadata.ts registers it. No production component reads the value. The AgentsNavItem uses permissions.createChat, not this metadata. Compare with tasks-tab-visible, which IS consumed by TasksNavItem.

The mock MockAgentsTabVisible in entities.ts:565 is still false while production is true. The entire pipeline (backend goroutine, HTML template field, metadata registration, stale mock) is dead weight.

11 of 17 reviewers flagged this independently. "Delete AgentsTabVisible from htmlState, remove the goroutine in populateHTMLState, remove the agents-tab-visible registration from useEmbeddedMetadata.ts, and remove the mock. This eliminates the class of bug where a stale or mismatched embedded boolean silently controls UI visibility without any consumer." (Meruem)

🤖

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.

DEREM-5: Done in 74140b6 — removed the entire pipeline (htmlState field, populateHTMLState goroutine, HTML meta tag, useEmbeddedMetadata registration, MockAgentsTabVisible).

Comment thread cli/agents.go Outdated

if _, ok := runModel.(expChatsTUIModel); !ok {
if _, ok := runModel.(chatsTUIModel); !ok {
return xerrors.New(fmt.Sprintf("unknown model found %T (%+v)", runModel, runModel))

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.

Nit [DEREM-6] xerrors.New(fmt.Sprintf(...)) should be xerrors.Errorf(...), which is the idiomatic pattern and used everywhere else in this file.

return xerrors.Errorf("unknown model found %T (%+v)", runModel, runModel)

(Leorio)

🤖

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.

DEREM-6: Done in eeb8201 — switched to xerrors.Errorf and dropped the now-unused fmt import.

deansheather added a commit that referenced this pull request Apr 28, 2026
Address Copilot review feedback on #24432: after dropping the
experiment flag, the Workspaces page was fetching chatsByWorkspace for
every user with workspaces, even users who can't create chats. The
endpoint still runs a DB query + RBAC post-filter and the downstream
UI (AgentsNavItem, chat link icon in the workspaces table) is already
hidden for users without createChat, so the fetch is pure waste for
them.

Gate the useQuery on permissions.createChat, matching the existing
canCreateChat pattern used in Navbar.tsx and AgentCreatePage.tsx.
deansheather added a commit that referenced this pull request Apr 28, 2026
Per coder-agents-review[bot] feedback:

- DEREM-1 (P2): docs/ai-coder/agents/getting-started.md said the Chats
  API was 'experimental'; chats-api.md was already updated to 'beta' in
  the rebase. Sync getting-started.md so both docs agree.

- DEREM-3 (P3): coderd/mcp_test.go's mcpDeploymentValues docstring
  still claimed it returned values 'with the agents experiment
  enabled'. Drop the stale claim and simplify the now-trivial
  function body.

- DEREM-4 (P3): docs/ai-coder/agents/early-access.md heading 'Enable
  Coder Agents' implied an enablement procedure, but the body says
  'No experiment flags are required.' Rename to 'Set up Coder Agents'.

- DEREM-6 (Nit): cli/agents.go used xerrors.New(fmt.Sprintf(...));
  switch to xerrors.Errorf(...) to match the rest of the file. Drop
  the now-unused fmt import.
deansheather added a commit that referenced this pull request Apr 28, 2026
Per PR #24432 review feedback (DEREM-5): the AgentsTabVisible
metadata pipeline (Go htmlState field, populateHTMLState goroutine,
HTML meta tag, useEmbeddedMetadata registration, MockAgentsTabVisible)
has zero production consumers. Compare with tasks-tab-visible, which
NavbarView.tsx:220 actually reads. AgentsNavItem already gates on
permissions.createChat.

The whole pipeline is now dead weight, with a stale mock value (false)
that disagrees with the unconditional production value (true). Removing
the entire chain rather than just toggling the mock eliminates the
class of bug where a stale embedded boolean silently controls UI
visibility without any consumer.

- site/site.go: drop the AgentsTabVisible field and its goroutine.
- site/index.html: drop the agents-tab-visible meta tag.
- site/src/hooks/useEmbeddedMetadata.ts: drop the registration.
- site/src/hooks/useEmbeddedMetadata.test.ts: drop the test cases.
- site/src/testHelpers/entities.ts: drop MockAgentsTabVisible.
@deansheather deansheather force-pushed the remove-agents-experiment-flag branch from d37c1ee to 74140b6 Compare April 28, 2026 08:17
@deansheather

Copy link
Copy Markdown
Member Author

Thanks for the review! Addressed in the latest force-push:

  • DEREM-1 (P2): Fixed in eeb8201docs/ai-coder/agents/getting-started.md now says "in beta" to match chats-api.md.
  • DEREM-2 (P3): PR description updated; the rename is now described as completed (commit 8e8cc8f) and the description no longer claims files still use exp prefixes.
  • DEREM-3 (P3): Fixed in eeb8201coderd/mcp_test.go's mcpDeploymentValues doc comment no longer claims it enables the agents experiment.
  • DEREM-4 (P3): Fixed in eeb8201 (replied inline).
  • DEREM-5 (P4): Fixed in 74140b6 — full AgentsTabVisible pipeline removed (replied inline).
  • DEREM-6 (Nit): Fixed in eeb8201 (replied inline).

Also rebased onto latest main (70d6efa311) along the way; resolved one conflict in coderd/roles.go where main moved AgentsAccessRole from a site role to an org-scoped system role (PR #24438), so the siteRoles = append(...) line is no longer needed and was dropped.

make pre-commit passed locally on every commit. Should be ready to merge once CI is green.

@deansheather

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review coder-agents-review 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.

Round 2. All 7 R1 findings (DEREM-1 through DEREM-7) confirmed fixed. The AgentsTabVisible dead code pipeline (DEREM-5) was cleaned thoroughly: zero references remain across Go, TypeScript, HTML, and test mocks. The docs fixes (DEREM-1, DEREM-4), stale comment updates (DEREM-3), PR description correction (DEREM-2), and xerrors.Errorf fix (DEREM-6) are all verified. DEREM-7 was resolved by the rebase absorbing PR #24438.

Severity count (new this round): 1 P3, 1 Nit.

The P3 is three stale Experimental(agents) comments in coderd/coderd.go that survived the cleanup. The PR already removed one identical pattern at line 1156 in R1; three siblings at lines 771, 2155, and 2157 were missed. Line 771 also has a latent emdash (U+2014) that will break make lint/emdash the moment anyone edits that line.

"The line 771 comment also contains an emdash, which violates the project's make lint/emdash rule. It is not caught today because the emdash check runs in changed mode and this line was not in the diff, but editing the line for any reason will trigger the lint failure." (Pariston)


coderd/coderd.go:771

P3 [DEREM-8] Three stale Experimental(agents) comments survive the cleanup:

  • Line 771: { // Experimental: agents — chat daemon and git sync worker initialization.
  • Line 2155: // Experimental(agents): chatDaemon handles background processing...
  • Line 2157: // Experimental(agents): gitSyncWorker refreshes stale chat diff statuses...

This PR already removed the identical pattern at line 1156 (// Experimental(agents): chat API routes gated by ExperimentAgents.). These three siblings were missed.

Line 771 also contains an emdash (U+2014), which is a latent make lint/emdash failure. It won't fire today because the emdash check runs in changed mode, but editing this line for any reason will trigger it.

Fix: reword all three to drop the Experimental prefix and the emdash. For example: { // Chat daemon and git sync worker initialization.

(Pariston)

🤖

docs/ai-coder/agents/getting-started.md:3

Nit [DEREM-9] "enabling Coder Agents" is stale since the enablement step was removed. The remaining steps are configuring a provider, granting a role, and starting an agent.

Consider changing to "setting up" or "configuring" to match the actual flow. The early-access.md heading was already updated from "Enable" to "Set up" for the same reason (DEREM-4).

(Leorio)

🤖

🤖 This review was automatically generated with Coder Agents.

deansheather added a commit that referenced this pull request Apr 28, 2026
Per coder-agents-review[bot] round 2 feedback:

- DEREM-8 (P3): Drop the 'Experimental(agents)' / 'Experimental:
  agents' prefix from three stale comments in coderd/coderd.go that
  the round-1 cleanup missed:
    - line 771: '{ // Experimental: agents [emdash] chat daemon and...'
    - line 2155: '// Experimental(agents): chatDaemon...'
    - line 2157: '// Experimental(agents): gitSyncWorker...'
  Line 771 also contained a literal emdash that would have tripped
  make lint/emdash the next time anyone edited the line; the new
  wording uses an ASCII period instead.

- DEREM-9 (Nit): Reword 'enabling Coder Agents' in
  docs/ai-coder/agents/getting-started.md to 'setting up Coder
  Agents'. The enablement step was removed in the round-1 cleanup,
  matching the same change made to early-access.md's heading
  (DEREM-4).
@deansheather

Copy link
Copy Markdown
Member Author

Round 2 addressed in 63a27a1:

  • DEREM-8 (P3): Reworded all three stale Experimental(agents) comments in coderd/coderd.go (lines 771, 2155, 2157). The line-771 comment also dropped its literal emdash so it no longer carries a latent make lint/emdash failure.
  • DEREM-9 (Nit): Reworded docs/ai-coder/agents/getting-started.md intro from "enabling Coder Agents" to "setting up Coder Agents" to match the early-access.md heading change from DEREM-4.

make pre-commit passes (lint/emdash + lint/go + lint/ts all green). I also re-grepped for Experimental(agents) / Experimental: agents / the agents experiment outside plans/ and the result is empty.

@deansheather

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review coder-agents-review 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.

Round 3. All 9 findings (DEREM-1 through DEREM-9) confirmed fixed across three rounds. No new findings from Netero or the panel (7 reviewers).

Clean experiment removal. The ExperimentAgents flag is fully excised, the AgentsTabVisible dead code pipeline is gone, docs are consistent ("beta" everywhere), stale comments are updated, the CLI graduated from coder exp agents to coder agents, and the emdash lint exclusion for golden files is correctly scoped.

"The problem is correctly understood. The solution is proportional. The fix is at the right level." (Pariston)

🤖 This review was automatically generated with Coder Agents.

Remove the ExperimentAgents feature flag so the Agents feature is
always available without requiring --experiments=agents. The feature
is now in beta.

Backend:
- Remove RequireExperimentWithDevBypass middleware from chat and MCP
  server routes in coderd/coderd.go
- Always include AgentsAccessRole in assignable site roles
- Always set AgentsTabVisible to true in site/site.go
- Make blob: CSP img-src addition unconditional
- Remove ExperimentAgents constant, DisplayName case, and
  ExperimentsKnown entry from codersdk/deployment.go

Frontend:
- Remove experiment check from AgentsNavItem (show when user has
  canCreateChat permission)
- Remove agentsEnabled experiment check from WorkspacesPage
- Add FeatureStageBadge with contentType=beta next to the Coder
  logo in the Agents sidebar (desktop and mobile)

Docs:
- Remove experiment flag setup instructions from early-access.md
  and getting-started.md
- Update chats-api.md to say beta instead of experimental

Tests:
- Remove ExperimentAgents setup from all test files

Existing deployments that still pass --experiments=agents will get a
harmless 'ignoring unknown experiment' warning on startup.
Move the agents TUI command from the experimental command tree to the
core subcommands, so it is available as "coder agents" instead of
"coder exp agents".

- Move r.agentsCommand() from AGPLExperimental() to CoreSubcommands()
  in cli/root.go (alphabetically sorted at the top).
- Drop the "agent" alias to avoid colliding with the hidden
  "coder agent" command used by the workspace agent binary.
- Remove leftover ExperimentAgents references introduced during
  rebase on main in cli/exp_agents_e2e_helpers_test.go and
  coderd/x/chatd/chatd_test.go.
- make gen regenerated docs/reference/cli/agents.md, the cli index,
  and the --help golden file.

The files are still named exp_agents_*.go for now; renaming them and
internal identifiers (expChatsTUIModel, etc.) is a mechanical cleanup
that can follow in a separate PR.
The agents command graduated from the experimental command tree in the
previous commit; update startExpAgentsSession so it invokes the new
top-level command path.
Follow-up to "remove agents experiment flag and mark feature as beta":

- coderd/x/chatd/integration_test.go, coderd/mcp_test.go: drop stale
  'with the agents experiment' wording from comments that no longer
  configure the experiment.
- docs/manifest.json: remove 'experimental' from the Chats API sidebar
  description now that docs/ai-coder/agents/chats-api.md calls the API
  'beta'.
…entifiers

The 'coder agents' TUI graduated out of the experimental command tree,
but the implementation files (cli/exp_agents_*.go) and internal symbols
still carried 'exp' prefixes. This is the mechanical cleanup promised
in the preceding "graduate coder exp agents" commit.

- Rename cli/exp_agents*.go -> cli/agents*.go (15 files, including the
  newly added cli/exp_agents_diff{,_test}.go from #24512).
- Rename internal identifiers:
    expChatsTUIModel       -> chatsTUIModel
    newExpChatsTUIModel    -> newChatsTUIModel
    expAgentsPtr           -> agentsPtr
    expAgentsSession       -> agentsSession
    setupExpAgentsBackend  -> setupAgentsBackend
    startExpAgentsSession  -> startAgentsSession
    TestExpAgents*         -> TestAgents*

Two CI-driven cleanups bundled here so the rename commit passes
pre-commit under the new repo-wide 'no emdash/endash' lint rule:

- plans/CODAGT-156-remove-experimental-flags.md: normalize em-dashes
  to colons/hyphens. The plan doc is new-vs-main so its lines are
  scanned by scripts/check_emdash.sh.
- scripts/check_emdash.sh: exclude cli/testdata/*.golden and
  enterprise/cli/testdata/*.golden from the scan. serpent's CLI help
  renderer emits emdash borders around the 'Run coder --help' footer,
  so every generated help golden file contains them. The newly added
  coder_agents_--help.golden tripped the check; the exclusion matches
  what's already true for all existing goldens.

Left intentionally untouched:
- expClient (local variable of type *codersdk.ExperimentalClient; the
  experimental API client is a separate concept from the graduated CLI).
- coderd/exp_chats*.go and enterprise/coderd/exp_chats_test.go (the
  chat API routes still live under /api/experimental/chats).
- Other cli/exp_*.go files (still-experimental commands like chat,
  mcp, rpty, prompt, sync).
Address Copilot review feedback on #24432: after dropping the
experiment flag, the Workspaces page was fetching chatsByWorkspace for
every user with workspaces, even users who can't create chats. The
endpoint still runs a DB query + RBAC post-filter and the downstream
UI (AgentsNavItem, chat link icon in the workspaces table) is already
hidden for users without createChat, so the fetch is pure waste for
them.

Gate the useQuery on permissions.createChat, matching the existing
canCreateChat pattern used in Navbar.tsx and AgentCreatePage.tsx.
Per coder-agents-review[bot] feedback:

- DEREM-1 (P2): docs/ai-coder/agents/getting-started.md said the Chats
  API was 'experimental'; chats-api.md was already updated to 'beta' in
  the rebase. Sync getting-started.md so both docs agree.

- DEREM-3 (P3): coderd/mcp_test.go's mcpDeploymentValues docstring
  still claimed it returned values 'with the agents experiment
  enabled'. Drop the stale claim and simplify the now-trivial
  function body.

- DEREM-4 (P3): docs/ai-coder/agents/early-access.md heading 'Enable
  Coder Agents' implied an enablement procedure, but the body says
  'No experiment flags are required.' Rename to 'Set up Coder Agents'.

- DEREM-6 (Nit): cli/agents.go used xerrors.New(fmt.Sprintf(...));
  switch to xerrors.Errorf(...) to match the rest of the file. Drop
  the now-unused fmt import.
Per PR #24432 review feedback (DEREM-5): the AgentsTabVisible
metadata pipeline (Go htmlState field, populateHTMLState goroutine,
HTML meta tag, useEmbeddedMetadata registration, MockAgentsTabVisible)
has zero production consumers. Compare with tasks-tab-visible, which
NavbarView.tsx:220 actually reads. AgentsNavItem already gates on
permissions.createChat.

The whole pipeline is now dead weight, with a stale mock value (false)
that disagrees with the unconditional production value (true). Removing
the entire chain rather than just toggling the mock eliminates the
class of bug where a stale embedded boolean silently controls UI
visibility without any consumer.

- site/site.go: drop the AgentsTabVisible field and its goroutine.
- site/index.html: drop the agents-tab-visible meta tag.
- site/src/hooks/useEmbeddedMetadata.ts: drop the registration.
- site/src/hooks/useEmbeddedMetadata.test.ts: drop the test cases.
- site/src/testHelpers/entities.ts: drop MockAgentsTabVisible.
Per coder-agents-review[bot] round 2 feedback:

- DEREM-8 (P3): Drop the 'Experimental(agents)' / 'Experimental:
  agents' prefix from three stale comments in coderd/coderd.go that
  the round-1 cleanup missed:
    - line 771: '{ // Experimental: agents [emdash] chat daemon and...'
    - line 2155: '// Experimental(agents): chatDaemon...'
    - line 2157: '// Experimental(agents): gitSyncWorker...'
  Line 771 also contained a literal emdash that would have tripped
  make lint/emdash the next time anyone edited the line; the new
  wording uses an ASCII period instead.

- DEREM-9 (Nit): Reword 'enabling Coder Agents' in
  docs/ai-coder/agents/getting-started.md to 'setting up Coder
  Agents'. The enablement step was removed in the round-1 cleanup,
  matching the same change made to early-access.md's heading
  (DEREM-4).
@deansheather deansheather force-pushed the remove-agents-experiment-flag branch from 63a27a1 to 9d48184 Compare April 30, 2026 13:32
@deansheather

Copy link
Copy Markdown
Member Author

/coder-agents-review

@coder-agents-review coder-agents-review 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.

Round 4. Rebase-only round (new base 07e86ae). No new findings from Netero or the panel (6 reviewers). All 9 prior findings remain fixed. The rebase introduced no regressions.

"Pulled every thread I could find across this diff. The removal is thorough and consistent." (Hisoka)

🤖 This review was automatically generated with Coder Agents.

The CODAGT-156 implementation plan was a working document that
shouldn't have been committed to the repo. Implementation is
complete; the plan no longer needs to live alongside the source.
@deansheather deansheather merged commit e575250 into main Apr 30, 2026
33 of 35 checks passed
@deansheather deansheather deleted the remove-agents-experiment-flag branch April 30, 2026 15:49
@github-actions github-actions Bot locked and limited conversation to collaborators Apr 30, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants