Commit Graph

5273 Commits

Author SHA1 Message Date
Cian Johnston d0a51da0a9 feat: classify provider_disabled 503 as non-retryable (#25800)
Builds on top of https://github.com/coder/coder/pull/25794

Adds a new `provider_disabled` error classification in `chatd` with the
corresponding plumbing to classify it as non-retryable. Also adds a
story for how this particular error kind is displayed in the UI.
2026-05-29 13:14:04 +01:00
Danielle Maywood 4144eb3c4f fix(site/src/pages/AgentsPage): avoid stale live tail spacing (#25846) 2026-05-29 12:55:16 +01:00
Sas Swart a586b7e5e0 feat: add boundary_log rbac resource (#24810)
RFC: [Bridge ↔ Boundaries Correlation
RFC](https://www.notion.so/coderhq/Gateway-and-Firewall-Correlation-RFC-31ad579be592803aa8b3d48348ccdde9)

Register a dedicated `boundary_log` RBAC resource type with `create`,
`read`, and `delete` actions, replacing the placeholder
`rbac.ResourceAuditLog` and `rbac.ResourceSystem` references previously
used in the dbauthz layer.

Create is granted at user-level so workspace agents can only write logs
owned by their workspace owner, preventing cross-workspace log
fabrication. Delete is restricted to `DBPurge` only; no human role
(including owner) can delete boundary logs.

| Subject | Create (own) | Create (other) | Read (all) | Delete |
|---|---|---|---|---|
| Workspace agent | yes | no | no | no |
| Owner (site admin) | yes (via member) | no | yes | no |
| Auditor | no | no | yes | no |
| DBPurge | no | no | no | yes |

### Changes

- **RBAC policy & resource definition**: add `boundary_log` to
`policy.go` and generate `ResourceBoundaryLog` object, scope constants,
and codersdk/TypeScript types.
- **dbauthz authorization**: replace all
`ResourceAuditLog`/`ResourceSystem` placeholders with
`ResourceBoundaryLog`. `InsertBoundaryLog` and `InsertBoundarySession`
derive the workspace owner from the agent and authorize with
`.WithOwner()` for user-scoped create.
- **Role assignments:**
- **Owner (site):** read only. Excluded from `allPermsExcept` wildcard;
create is inherited from member at user-level.
- **Member (user-level):** create. User-scoped so agents can only write
logs they own.
  - **Auditor (site):** read.
- `boundary_log` is excluded from org-admin, org-member, and
org-service-account `allPermsExcept` calls for consistency with
`ResourceBoundaryUsage`.
- **System subjects:**
- **DB Purge** (`SubjectTypeDBPurge`): delete. The only subject that can
remove boundary logs.
- **Workspace agent scope**: `ResourceBoundaryLog` with wildcard ID in
the agent scope allow-list (necessary for creation since no pre-existing
ID exists). User-level role scoping prevents deployment-wide access.
- **DB migration** (`000510_boundary_log_scopes`): add `boundary_log:*`,
`boundary_log:create`, `boundary_log:delete`, `boundary_log:read` enum
values to `api_key_scope`.
- **Test coverage**: `BoundaryLogCreate` (user-scoped, only matching
owner succeeds), `BoundaryLogDelete` (all human roles denied),
`BoundaryLogRead` (owner + auditor). dbauthz mock tests set up workspace
agent lookups for owner derivation.
- **Generated docs**: update OpenAPI specs, API reference docs, and
frontend type definitions.

---------

Co-authored-by: Muhammad Danish <mdanishkhdev@gmail.com>
Co-authored-by: Coder Agents <coder-agents-review[bot]@users.noreply.github.com>
2026-05-29 12:50:39 +02:00
Danielle Maywood 88060b846e style(site): use lightbulb icon for thinking (#25844) 2026-05-29 11:35:05 +01:00
Cian Johnston 78d556fffc feat(site/src/pages/AgentsPage): show error details for generic errors (#25803)
Error messages in agent chat now expose the actual error detail
instead of hiding it entirely. Also captures API response detail
for generic errors that previously dropped it.
2026-05-29 11:34:54 +01:00
TJ a801d996e7 fix(site): update models settings page description text (#25830)
Updates the description text on the Agent Settings > Models page
(`/agents/settings/models`).

**Before:** "Choose which models from your configured providers are
available for users to select. You can set a default and adjust context
limits."

**After:** "Choose which models from your configured providers are
available for Coder Agents. Set a default and adjust context limits."

> Generated by Coder Agents on behalf of @tracyjohnsonux
2026-05-29 14:33:51 +10:00
TJ 650069f949 feat: update search dialog with filter pills and default view (#25753)
Update the ChatSearchDialog with four interaction states:

1. **Default (empty)**: quick actions (New chat, Settings, Personal
Skills, View usage) + recent chats list
2. **Focused**: filter-by dropdown overlay with clickable chips (Unread,
Archived, PR status, Diff URL)
3. **Active search**: filter pills and/or freeform text with debounced
live results showing "N results" count
4. **Parameterized filter**: incomplete pill (dashed border) for filters
needing a value (e.g. `pr_status:`); Space or Enter commits the value
into a solid pill

Filter pills and freeform text are combinable. Backspace on empty text
removes the last pill. The filter dropdown overlays content below and
dismisses on blur or Escape.

Changes:
- `ChatSearchDialog.tsx`: manages structured filter state with separate
`incompleteFilterKey` tracking, renders filter dropdown, passes recent
chats and quick action callbacks
- `ChatSearchInput.tsx`: renders completed filter pills (solid border, x
dismiss) and incomplete pills (dashed border) inline with the text input
- `ChatSearchResults.tsx`: default view shows quick actions + recent
chats instead of the old help text; "No matching chats" is centered in
the modal
- `ChatsSidebar.tsx`: passes `recentChats`, `onNewChat`,
`onOpenSettings` to the dialog

<details>
<summary>Implementation notes</summary>

- No backend changes; reuses existing `chatSearch()` API and
`normalizeChatSearchInput()` normalizer
- Filter state uses a clean model: `filters` array for committed filters
+ `incompleteFilterKey` string for the parameterized filter being typed;
`freeText` serves dual purpose (filter value when incomplete key is set,
otherwise freeform search)
- The filter dropdown is absolutely positioned (`top-full`) below the
search input, dismisses via container `onBlur` with
`contains(relatedTarget)` check
- Quick action links (Personal Skills, View usage) use `Link` components
that close the dialog on click

> Generated with [Coder Agents](https://coder.com/agents)

</details>
2026-05-28 21:08:36 -07:00
TJ d3bedb4a93 refactor(site): promote search to full-width sidebar nav item (#25595)
Move the chat search button from a subtle icon next to the filter in the
Chats header to a prominent full-width nav item below New Agent. The
search bar shows a magnifying glass icon and "Search" label by default,
with the keyboard shortcut badge (`⌘ K` / `Ctrl K`) and background
appearing on hover/focus.

Also pull the Chats header and filter row out of the scroll area so the
scrollbar only covers the chat list content, and align the logo row with
the nav item content inset.

> 🤖 Generated by Coder Agents on behalf of @tracyjohnsonux
2026-05-28 15:03:20 -07:00
Jon Ayers c248dfb437 fix: escape agent log HTML (#25808) 2026-05-28 14:43:07 -05:00
Cian Johnston 7ea0eff94e fix: improve chat audit log descriptions and diff rendering (#25728)
Chat ACL audit diffs rendered as `[object Object]` because the diff
viewer called `.toString()` on object values. Common chat operations
(archive, share) showed generic "updated chat" descriptions instead of
semantic ones.

Add `chatAuditLogDescription` to derive semantic descriptions from the
audit diff for successful chat writes: "archived/unarchived chat" for
archive toggles, "updated sharing for chat" for ACL-only changes.
Extract diff value formatting into `formatAuditDiffValue`, which renders
object values as deterministic compact JSON with sorted keys, fixing the
`[object Object]` rendering for chat ACLs and any other object-valued
fields. The previous `determineIdPSyncMappingDiff` workaround for IdP
sync mappings was removed because the generic formatting handles it.

Closes CODAGT-513

> Generated by Coder Agents on behalf of @johnstcn
2026-05-28 18:37:57 +01:00
TJ ebf56ebd12 feat(site): desktop panel toolbar, zoom modes, and pop-out window (#25585)
Redesigns the agent desktop panel with a persistent toolbar, zoom modes,
and a detachable pop-out window.

## Changes

**Toolbar** (`DesktopToolbar`)
- Persistent top bar with right-aligned controls: Take/Release control,
Zoom toggle, Detach
- All buttons use consistent `subtle` variant with icon + label
- `h-8` height, `bg-surface-primary` background with bottom border

**Zoom modes**
- Defaults to fit-to-window (`scaleViewport = true`) so the full
1920x1080 desktop is visible
- Toggle to native 100% resolution via toolbar button or keyboard
shortcuts (`Ctrl+0` fit, `Ctrl+1` native)
- noVNC background color overridden from hardcoded `rgb(40,40,40)` to
`--surface-secondary` so letterbox margins match the app theme in light
and dark mode

**Pop-out window**
- New route at `/agents/:agentId/desktop` for a dedicated desktop window
- Opens via toolbar "Detach" button at 50% of screen size, centered
- BroadcastChannel coordination: sidebar shows placeholder with "Bring
back" button
- Closing the pop-out window automatically restores the sidebar panel

**Other**
- `useDesktopConnection` hook accepts `scaleViewport` option, synced to
the RFB instance via a secondary effect
- `DesktopPanelContext` extended with `agent` and `workspace` fields
- Replaces the previous hover-overlay take/release control UX with
toolbar buttons

> Generated by Coder Agents on behalf of @tracyjohnsonux
2026-05-28 09:26:05 -07:00
Danielle Maywood 0d1340a430 fix: collapse agent command output by default (#25748) 2026-05-28 16:54:52 +01:00
Steven Masley 4591212482 feat: implement SCIM handler for SCIM 2.0 compliance (#25572)
Rewrites the SCIM 2.0 user provisioning handler to be RFC 7644
compliant. Verified against an external IdP Okta.

Behavior is OPT IN
2026-05-28 10:00:37 -05:00
Cian Johnston 6df1536256 fix: add missing_key error kind for missing chat api_key_id (#25783)
Refs CODAGT-486

- `codersdk/chats.go`: New `ChatErrorKindMissingKey` constant and
`AllChatErrorKinds` entry
- `coderd/x/chatd/chaterror/message.go`: `terminalMessage` and
`retryMessage` cases
- `coderd/x/chatd/model_routing_aibridge.go`: Pre-classify error with
`WithClassification`
- `coderd/x/chatd/model_routing_internal_test.go`: Classification
assertion on production path (CRF-2)
- `chatStatusHelpers.ts`: Frontend title "Chat interrupted"
- `LiveStreamTail.stories.tsx`: Storybook story with `detail` assertion
- `docs/ai-coder/ai-gateway/clients/coder-agents.md`: Troubleshooting
entry
- Tests: classification round-trip, terminal message, metrics kind
enumeration

> Generated with [Coder Agents](https://coder.com/agents) on behalf of
@johnstcn
2026-05-28 15:50:52 +01:00
Danielle Maywood 8600b59aae fix(site): normalize thinking transcript row (#25749) 2026-05-28 14:49:10 +01:00
TJ cfa343e456 refactor(site): update BYOK link to use "View docs" on AI settings page (#25743)
Changes the "Manage deployment-wide BYOK" link on the AI Providers
settings page (`/ai/settings`) to "View docs", matching the pattern used
on the provisioner keys page (`/organizations/{org}/provisioner-keys`).

### Changes
- Swapped `Link` from `react-router` to `#/components/Link/Link` (uses
`href` instead of `to`)
- Removed `target="_blank"` and `rel="noreferrer"`: the link now
navigates in the same tab, matching the provisioner keys page convention
- Changed link text from "Manage deployment-wide BYOK" to "View docs"

> Generated by Coder Agents on behalf of @tracyjohnsonux
2026-05-28 08:50:10 +02:00
Sas Swart 3b8a9ff802 feat: add preset query parameter for workspace creation deeplinks (#24328)
Co-authored-by: Atif Ali <atif@coder.com>
2026-05-28 10:42:53 +05:00
Michael Suchacz 3cf867f84a fix(site/src/pages/AgentsPage): make other-user chats read-only (#25736)
Other-user agent chats showed a banner that implied prompts would run as
the owner, but submitting from that view is forbidden.

This updates the banner to identify the chat owner and makes chats owned
by another user read-only in the UI by disabling the composer and hiding
inline send or edit follow-up actions.

> Mux working on behalf of Mike.
2026-05-27 18:10:10 +02:00
Danielle Maywood 2d40a40c57 fix(site): tighten execute tool duration spacing (#25739) 2026-05-27 16:57:05 +01:00
Danny Kopping 2770bdc9d1 feat: route extra ai_provider_types through OpenAI and Anthropic providers (#25722)
_Disclosure:_ _produced_ _with_ _Claude_ _Opus_ _4\.7_

AI Gateway only supports Anthropic (+Bedrock), OpenAI, and Copilot providers at present. All other types (Vercel, Gemini, etc) will be mapped to OpenAI since they support OpenAI-compatible endpoints.
2026-05-27 16:16:05 +02:00
Danielle Maywood d1e27889eb fix(site): improve chat sharing mobile layout (#25687) 2026-05-27 15:03:29 +01:00
Danielle Maywood 5603be19cc feat(site): add transcript tool icons (#25724) 2026-05-27 14:43:14 +01:00
Cian Johnston 6acfe6c835 fix: classify quota errors as usage_limit instead of auth (#25676)
Fixes CODAGT-484.

- Removed "quota", "billing", "insufficient_quota", "payment required"
from `authStrongPatterns`
- Added `usageLimitPatterns` slice with those patterns
- Added `usageLimitMatch` signal and rule between overloaded and
authStrong in priority
- Added terminal/retry messages for `ChatErrorKindUsageLimit`
- Simplified auth message (removed billing reference)
- Frontend: conditional `!usageLimitStatus.provider` guard on the "View
Usage" Alert
- Added `TestClassify_UsageLimitBeatsAuth` with 5 cases including real
production OpenAI error
- Added `ProviderQuotaExceeded` story asserting no "View Usage" link and
correct `ChatStatusCallout` rendering

> Generated with [Coder Agents](https://coder.com/agents)
2026-05-27 09:45:36 +01:00
Jake Howell 9c10ec2ca7 fix: resolve mui <TimelineDateRow /> regression (#25716) 2026-05-27 18:36:55 +10:00
TJ 916094c71c feat(site): replace usage bars with ring indicators (#25708)
Replaces the linear progress bars and text labels in the sidebar footer
usage trigger with SVG donut ring charts that show the section icon
centered inside each ring.

## Changes

- **`SvgRingProgress`**: shared SVG component used by both
`UsageIndicator` and `ContextUsageIndicator`
- Ring colors follow the existing severity system
(normal/warning/exceeded)
- Hover tooltips show "Spend $12.50" and "Workspaces 30/100"
- Dropdown menu content unchanged; full usage details still appear on
click
- Removed dead `summaryValue` field and `size="compact"` variant
- Updated stories to cover ring trigger rendering and dropdown usage
details

> Generated by Coder Agents on behalf of @tracyjohnsonux
2026-05-26 22:01:31 -07:00
TJ 2afb33ac5e feat(site/src/pages/AgentsPage): inline setup notice banner with admin/member distinction (#25518)
Replaces the blocking Dialog modal setup notice with a context-aware
inline banner above the chat input, with different messaging for admins
and members.

## Inline notice banner

The `AgentSetupNotice` component now renders as a `bg-surface-tertiary`
inline box instead of an unclosable `Dialog` modal. The notice sits
above the chat composer using negative margin overlap, and the composer
is forced opaque (`bg-surface-secondary`) when the notice is present so
the banner doesn't bleed through the semi-transparent desktop
background.

Three states based on role and configuration:
- **Admin, no providers or models**: links to both provider and model
setup
- **Admin, missing provider only**: link to provider setup
- **Admin, has providers but no models**: link to model setup only
- **Member, no models available**: generic "your admin is still getting
things set up" message

The admin/member distinction is determined via
`permissions.editDeploymentConfig` and applied in both `AgentChatPage`
and `AgentCreatePage`.

## Conflict resolution notes

During merge with main, the following were adapted:
- Sidebar filter props updated to main's
`sidebarFilters`/`onSidebarFiltersChange` pattern (replacing old
`archivedFilter`)
- Accepted `Sidebar/` -> `ChatsSidebar/` directory refactor from main
- Dropped `hasArchivedChats` query (its sidebar consumer was removed in
the refactor)
- Provider link updated to `/ai/settings` (new AI settings page)

> Generated with the assistance of Coder Agents on behalf of
@tracyjohnsonux

---------

Co-authored-by: jaaydenh <jaaydenh@users.noreply.github.com>
2026-05-26 21:00:53 -07:00
Zach 47ac4b309a feat: enforce per-user limits on user_secrets (#25588)
Add a Postgres trigger and matching codersdk constants that cap each
user's secrets in four dimensions: count (50), total stored value bytes
(200 KiB), env-injected stored value bytes (24 KiB), and env name length
(256 bytes). Without these caps a user could overflow the 4 MiB DRPC
agent manifest, the ~32 KiB Windows process env
block, or Linux/macOS ARG_MAX at workspace start. The trigger is the
source of truth on aggregates; the handler maps its check_violation
error into a 400 that names the per-user budget in stored
(post-encryption) bytes. A handler test exercises off-by-one at each cap
across POST and PATCH, plus per-user budget isolation.

Generated with help from Coder Agents.
2026-05-26 14:42:31 -06:00
Michael Suchacz 8b1705eb65 feat: route chatd provider traffic through aibridge (#25629)
## Summary

Routes chatd model calls backed by concrete AI Provider rows through the
in-process aibridge transport by default, with deployment options to use
direct provider routing when AI Gateway is disabled or chat AI Gateway
routing is disabled.

- Splits model routing into common, direct provider, and AI Gateway
paths behind a single deployment-mode entry point.
- Builds chatd models through explicit request, route, and options data.
Active API key attribution is passed explicitly instead of being hidden
inside generic model construction.
- For AI Gateway BYOK routes, resolves the user's provider key in chatd,
forwards it through provider-specific auth headers, and sets
`X-Coder-AI-Governance-Token` to the `delegated` marker so aibridge
preserves those headers while still stripping Coder-specific metadata.
- Keeps central provider credentials and deployment fallback credentials
out of forwarded provider auth headers, so AI Gateway central policy
remains authoritative.
- Redacts delegated provider auth from default string formatting to
avoid accidental plaintext logging of user BYOK credentials.
- Covers selected chat models, advisor overrides, title and quickgen
paths, subagent overrides, computer use model selection, and an
integration-style chat turn through the aibridge transport path.
- Persists initiating API key IDs on chat and queued user messages,
including subagent child messages, and fails closed for AI
Gateway-routed model builds without an active key.
- Removes unused `api_key_id` indexes while keeping the persistence
columns and foreign keys.
- Keeps the deployment option available through config and env parsing,
but hides it from CLI help and generated docs.
- Stabilizes the subagent poll fallback test so background CreateChat
processing cannot win the state transition under slower CI environments.

## Tests

- `go test ./coderd/x/chatd -run
'TestAIGatewayProviderAuthForUser|TestAIGatewayProviderAuthRedactsFormatting|TestResolveModelRouteForConfigAIGatewayProviderAuth|TestAIGatewayModelForwardsProviderAuth|TestProcessChat_AIGatewayRoutingUsesDelegatedAPIKey|TestAwaitSubagentCompletion'
-count=1`
- `go test ./coderd/aibridged -run
'TestServeHTTP_DelegatedAPIKey|TestServeHTTP_StripCoderToken' -count=1`
- `git diff --check HEAD~1..HEAD`
- `make lint`

> Mux working on behalf of Mike.
2026-05-26 19:31:52 +00:00
blinkagent[bot] dd741bd188 fix(site): only highlight Providers item on exact match in AI settings sidebar (#25700)
## Problem

When visiting `/ai/settings/governance`, both **AI Governance** and
**Providers** items in the AI settings subnav appear highlighted as
active.

## Cause

`SettingsSidebarNavItem` is built on react-router's `<NavLink>`, which
by default treats a link as active when the current URL **starts with**
the link's `to` path. Since `/ai/settings/governance` starts with
`/ai/settings`, the Providers item is also marked active.

## Fix

Pass `end` on the Providers nav item so it only matches when the path is
exactly `/ai/settings` (the index route). The `SettingsSidebarNavItem`
component already supports this prop for exactly this case.

Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com>
2026-05-26 19:23:13 +00:00
TJ be184a0591 fix(site): update providers description with BYOK docs link (#25680)
> 🤖 Generated with [Coder Agents](https://coder.com/agents) on behalf of
@tracyjohnsonux

Updates the providers page description to explain that providers power
Coder Agents, AI Gateway, and other LLM features. Adds a "Manage
deployment-wide BYOK" link to the docs.

Uses `<Link>` component and `docs()` helper per project conventions.
2026-05-26 12:03:29 -07:00
Danielle Maywood c96c1ab563 feat: add agents sidebar filters (#25402) 2026-05-26 20:00:37 +01:00
dylanhuff-at-coder 7887cff9d0 feat: add user secrets management page (#25371)
Adds the account settings UI for managing user secrets, including the
table, add/edit/delete dialog, Storybook coverage, and route/sidebar
entry.

Also updates the shared `FeatureStageBadge` beta variant with
dedicated beta styling, sizing, and label casing for the Secrets
page.

Stacked on #25370.

_This PR was generated by Coder Agents._
2026-05-26 11:51:00 -07:00
Jake Howell d80b484487 feat(site): promote AI settings to a top-level section (#25582)
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell.

Linear: [DEVEX-355](https://linear.app/coder/issue/DEVEX-355)

Fifth and final PR in a 5-PR stack splitting #25328. Surfaces the AI
settings section in the dashboard chrome and moves the existing AI
Governance page out of `/deployment`.

- `Navbar` / `NavbarView` / `DeploymentDropdown` gain a
`canViewAISettings` prop sourced from the `viewAnyAIProvider` permission
added in PR 2. The deployment dropdown gets a new AI entry that links to
`/ai/settings`.
- `DeploymentSidebarView` drops the AI-related entries that now live
under `/ai/settings`.
- `AISettingsSidebarView` expands to include AI Governance and a
cross-section link to Manage Coder Agents.
- `router.tsx` removes the `/deployment/ai-governance` route and mounts
the matching `/ai/settings/governance` child route under the new AI
settings layout.
- `ChatsSidebar` settings panel repoints the Providers link from
`/deployment/ai-providers` to `/ai/settings`.

<details>
<summary>Stack</summary>

1. #25579 jakehwll/DEVEX-355/01-primitives, primitives
2. #25580 jakehwll/DEVEX-355/02-api, API client and query layer
3. #25581 jakehwll/DEVEX-355/03-components, provider form components
4. #25583 jakehwll/DEVEX-355/04-pages, pages and routes
5. **jakehwll/DEVEX-355/05-section, section reshuffle (this PR)**

Replaces #25328 once the stack lands.
</details>
2026-05-26 16:50:36 +00:00
Jake Howell 0a7ac7c986 feat(site): add AI settings providers pages and routes (#25583)
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell.

Linear: [DEVEX-355](https://linear.app/coder/issue/DEVEX-355)

Fourth PR in a 5-PR stack splitting #25328. Wires the new `/ai/settings`
provider management UI.

- `AISettingsLayout` hosts the section under `/ai/settings` with a
sidebar outlet.
- `AISettingsSidebar(View)` shows a single "Providers" nav entry. The
remaining sidebar entries arrive with the broader AI settings section
reshuffle in the next PR.
- `ProvidersPage` lists configured AI providers via the queries added in
PR 2.
- `AddProviderPage` walks through provider-type selection and form
submission, with type-specific credential fields.
- `UpdateProviderPage` edits an existing provider with the same form
components.
- Storybook stories cover each view's loading, empty, populated, error,
and form states using the mock providers from `testHelpers/entities.ts`.
- `router.tsx` mounts the new `/ai/settings` layout with index, `add`,
and `:providerId` child routes. The `governance` child route lands
together with the dashboard navigation changes in the next PR.

Removes the now-unused knip ignore entries for
`src/api/queries/aiProviders.ts` and
`src/pages/AISettingsPage/ProvidersPage/components/addableProviderTypes.ts`,
and drops the matching `@lintignore` tags on `getProviderIcon` and
`MockAIProviders` since the pages and page stories now consume them.

<details>
<summary>Stack</summary>

1. #25579 jakehwll/DEVEX-355/01-primitives, primitives
2. #25580 jakehwll/DEVEX-355/02-api, API client and query layer
3. #25581 jakehwll/DEVEX-355/03-components, provider form components
4. **jakehwll/DEVEX-355/04-pages, pages and routes (this PR)**
5. jakehwll/DEVEX-355/05-section, section reshuffle

Replaces #25328 once the stack lands.
</details>
2026-05-26 16:38:34 +00:00
Jake Howell 99a00259eb feat(site): add AI settings provider form components (#25581)
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell.

Linear: [DEVEX-355](https://linear.app/coder/issue/DEVEX-355)

Third PR in a 5-PR stack splitting #25328. Adds the component-level
pieces used by the provider management pages landing in the next PR of
the stack.

- `ProviderForm` + `CredentialField` + a provider type-to-form mapping
for reading and editing the per-type credential and config fields, with
the form API map covered by unit tests.
- `ProviderIcon` resolves the bundled per-provider SVG icons and falls
back to a building glyph for unknown types.
- `ProviderRow` renders a single provider entry for the list view.
- `useUnsavedChangesPrompt` hook intercepts unsaved-form navigation.
- Storybook stories for `ProviderForm`, `ProviderIcon`, and
`ProviderRow` exercise each provider type and form state and consume the
mock providers from PR 2.

Stories now consume `MockAIProviderOpenAI` / `Anthropic` / `Bedrock` so
their per-mock `@lintignore` tags are removed; the `MockAIProviders`
aggregate and the `addableProviderTypes` / `aiProviders` query modules
keep their exclusions for the page stories in the next PR.

<details>
<summary>Stack</summary>

1. #25579 jakehwll/DEVEX-355/01-primitives, primitives
2. #25580 jakehwll/DEVEX-355/02-api, API client and query layer
3. **jakehwll/DEVEX-355/03-components, provider form components (this
PR)**
4. jakehwll/DEVEX-355/04-pages, pages and routes
5. jakehwll/DEVEX-355/05-section, section reshuffle

Replaces #25328 once the stack lands.
</details>
2026-05-26 16:27:41 +00:00
Jake Howell 5d39c833f8 feat(site): add AI provider API client and query layer (#25580)
> 🤖 This PR was written by Coder Agents on behalf of Jake Howell.

Linear: [DEVEX-355](https://linear.app/coder/issue/DEVEX-355)

Second PR in a 5-PR stack splitting #25328. Adds the frontend layer that
talks to the existing `/api/v2/ai/providers` endpoints already shipped
on `main`:

- API client: `getAIProviders`, `getAIProvider`, `createAIProvider`,
`updateAIProvider`, `deleteAIProvider`.
- React Query wrappers in `queries/aiProviders.ts` with a shared key
helper and matching cache invalidations.
- Mock fixtures for OpenAI, Anthropic, and Bedrock providers in
`testHelpers/entities.ts` for stories and unit tests.
- `viewAnyAIProvider` registered in `permissions.json` so the existing
permissions hook can read it.
- `viewAnyAIProvider` added to `canViewDeploymentSettings` so admins who
can only manage providers still see the deployment dropdown.

The `aiProviders` query module and the per-provider mocks are
temporarily added to the `knip` ignore list / annotated with
`@lintignore`; the next PRs in the stack consume them and remove the
exclusions.

<details>
<summary>Stack</summary>

1. #25579 jakehwll/DEVEX-355/01-primitives, primitives
2. **jakehwll/DEVEX-355/02-api, API client and query layer (this PR)**
3. jakehwll/DEVEX-355/03-components, provider form components
4. jakehwll/DEVEX-355/04-pages, pages and routes
5. jakehwll/DEVEX-355/05-section, section reshuffle

Replaces #25328 once the stack lands.
</details>
2026-05-26 16:13:11 +00:00
Jake Howell 8ae732000c feat(site): add UI primitives for the AI settings stack (#25579)
> 🤖 This PR was modified by Coder Agents on behalf of Jake Howell.

Linear: [DEVEX-355](https://linear.app/coder/issue/DEVEX-355)

First PR in a 5-PR stack splitting #25328. Adds the small UI primitives
the AI settings stack depends on.

- `FormField` accepts a `description` prop and renders a required
marker. `aria-describedby` is composed from the description, helper, and
error IDs.
- `PageHeader` title, subtitle, and caption forward `className` and
other intrinsic `h1`/`h2`/`span` props to their root elements.
- `AvatarData` gains an opt-in `truncate` prop that clips overflowing
title and subtitle with an ellipsis. Off by default so existing
consumers passing non-text nodes (icons, badges) do not clip silently.
- Bundles the Vercel provider icon (`vercel.svg`) and registers it in
`icons.json` and `externalImages.ts`.

No new pages or routes here; later PRs in the stack consume these
primitives.

<details>
<summary>Stack</summary>

1. **jakehwll/DEVEX-355/01-primitives, primitives (this PR)**
2. jakehwll/DEVEX-355/02-api, API client and query layer
3. jakehwll/DEVEX-355/03-components, provider form components
4. jakehwll/DEVEX-355/04-pages, pages and routes
5. jakehwll/DEVEX-355/05-section, section reshuffle

Replaces #25328 once the stack lands.
</details>
2026-05-27 02:01:53 +10:00
Danielle Maywood c56af60d12 feat(site/src/pages/AgentsPage/components): collapse sequential read file events (#25075) 2026-05-26 16:19:50 +01:00
Ethan e2f01e5531 chore: prettify agents usage indicator (#25428)
Restyles the Agents page usage trigger to match the new quota meter
presentation by Tracy.

The trigger now shows one compact row per section with the existing
severity colors, the same spend icon used in settings, a server icon for
workspace quota, and right-aligned counters. The related stories were
updated to reflect the new trigger layout.

**Before:**
<img width="318" height="332" alt="image"
src="https://github.com/user-attachments/assets/4c6087bd-7c14-4cb6-b2e7-26bb7a1d3e70"
/>

**After:**
<img width="323" height="353" alt="image"
src="https://github.com/user-attachments/assets/95bfb992-cab8-473e-838d-1dcbe246fe3d"
/>




Relates to CODAGT-197
2026-05-27 01:09:14 +10:00
Danny Kopping 90d8f56cc2 fix(site): rename "AI Bridge" to "AI Gateway" in paywall card (#25677)
*Disclaimer: implemented by a Coder Agent using Claude Opus 4.6*

## Summary

Renames "AI Bridge" to "AI Gateway" in the paywall card shown on the AI
Governance settings page when the feature is not entitled.

## Changes

In `PaywallAIGovernance.tsx`:
- Title: `AI Bridge` -> `AI Gateway`
- Description text: `AI Bridge provides...` / `AI Bridge requires...` ->
`AI Gateway provides...` / `AI Gateway requires...`
- Docs link label: `AI Bridge Docs` -> `AI Gateway Docs`
2026-05-26 17:08:45 +02:00
Jake Howell b4332443b3 fix: resolve stopWorkspaceIfRunning common path (#25639)
Closes #24333

This was a common setup in `updateWorkspace()` but was not appropriately
ported to `changeWorkspaceVersion()`. Some tests have been added also to
ensure this works 🙂 Simple smooth and easy.
2026-05-27 00:01:10 +10:00
Danny Kopping 282ab7de34 refactor: load AI providers from the database at startup (#25672)
Replace the env-based `BuildProviders` with a DB-backed loader. The database is now the single source of truth for runtime provider configuration; env config arrives via `SeedAIProvidersFromEnv` (run at boot) and `BuildProviders` reads it back as `aibridge.Provider` instances. `cli/server.go` and `enterprise/cli/server.go` both call the same path, so aibridged and aibridgeproxyd see the same provider set.

Per-provider `DumpDir` is replaced by a top-level `CODER_AI_GATEWAY_DUMP_DIR` base; each provider's effective dump path is `<base>/<provider name>`.
2026-05-26 15:57:01 +02:00
Mathias Fredriksson 32ed9f1f39 fix: use old_text/new_text in edit_files tool schema (#25658)
Models frequently confuse the search and replace fields in the
edit_files tool (CODAGT-312). Rename the model-facing JSON fields
to old_text/new_text so the intent is unambiguous.

Backend: custom UnmarshalJSON on editFileEdit falls back to
deprecated search/replace when old_text/new_text are empty. The
workspace agent API is unchanged; toSDKFiles maps old_text/new_text
back to search/replace for agent/agentfiles.

Frontend: normalizeEdit in parseEditFilesArgs accepts both
old_text/new_text and search/replace, normalizing to the internal
{ search, replace } representation so streaming diff rendering
works with either field naming convention.
2026-05-26 11:11:47 +03:00
Michael Suchacz 84240da0c1 fix(site/src/pages/AgentsPage): avoid skills popup flash (#25661)
When removing the `/` personal skill trigger, the popover content stayed
mounted during its close transition and briefly rendered the empty
skills state at the viewport origin.

This keeps the menu content mounted for stable Radix positioning,
preserves the last open menu state during the close transition, and adds
a Storybook regression for the backspace path.

> Mux is creating this PR on behalf of Mike.
2026-05-25 21:58:37 +02:00
Atif Ali 2ad2f7869d chore(site): rename AI Bridge Sessions dropdown to AI Sessions (#25656)
Renames the admin settings dropdown label from "AI Bridge Sessions" to
"AI Sessions". The link target (`/aibridge/sessions`) is unchanged.
2026-05-25 16:23:38 +00:00
Danny Kopping 4ddda3a9db feat: filter interceptions and sessions by provider name (#25640)
Allows filtering sessions & interceptions by provider name, and adds a test to vaidate that provider name is immutable (at least until #25606 lands).
2026-05-25 16:31:48 +02:00
Michael Suchacz ffc51ec8b3 feat(site/src/pages/AgentsPage): show MCP tool inputs (#25568)
Generic agent chat tool cards now render an `Input` section before the
existing output viewer, so MCP and workspace MCP tools expose the
arguments sent to the tool. Empty inputs stay hidden, model-intent
wrappers are stripped before display, and the formatted input is the
single source of truth for whether an input block renders.

Refs
https://linear.app/codercom/issue/CODAGT-260/show-mcp-tool-inputs-in-agent-chats

> Mux worked on this on Mike's behalf.
2026-05-25 12:09:03 +02:00
Tyler 814386dda7 fix(site): left-align template README content instead of centering in narrow column (#25487)
Closes #24183

## Changes

Drops `mx-auto` so README content left-aligns with the header. Bumps
padding from 24px to 32px and widens `max-w` from 800px to 860px for
breathing room.

Applied to both:
- `TemplateDocsPage.tsx`
- `StarterTemplatePageView.tsx`

> Generated with [Coder Agents](https://coder.com/agents)
2026-05-22 23:37:35 -07:00
Jaayden Halko ef3f95a7af fix(site/src): account for iOS visual viewport offset (#25619)
## Summary

- Compute mobile dropdown bottom offsets in layout-viewport coordinates,
matching the fixed Radix popover wrapper.
- Use `visualViewport.offsetTop` to clamp the above-composer popup
height when iOS WebKit pans the visual viewport for the soft keyboard.
- Align mobile dropdown width/left to the chat composer and add a
Storybook regression for shifted visual viewports.

## Testing

- `cd site && pnpm tsc --noEmit -p .`
- `cd site && pnpm test:storybook
src/pages/AgentsPage/components/ChatMessageInput/ChatMessageInput.stories.tsx`
- `cd site && pnpm lint`

## Manual mobile verification

Start dev mode with `./scripts/develop.sh`, open the forwarded port 8080
URL on a real iPhone in Safari and Chrome, focus the Agents chat input,
type `/`, and verify the personal skills popup appears directly above
the composer, stays within the visible viewport while the keyboard is
open, and scrolls internally for long lists.

Generated by Coder Agents.
2026-05-22 16:36:27 +01:00
Danny Kopping 0d9718e217 feat: add 'copilot' to ai_provider_type (#25616) 2026-05-22 16:10:37 +02:00