Skip to content

feat!: scope coderd_agents_model to organizations - #422

Merged
ethanndickson merged 13 commits into
mainfrom
org-chat-models/agents-model
Aug 31, 2026
Merged

feat!: scope coderd_agents_model to organizations#422
ethanndickson merged 13 commits into
mainfrom
org-chat-models/agents-model

Conversation

@ethanndickson

@ethanndickson ethanndickson commented Aug 25, 2026

Copy link
Copy Markdown
Member

Bumps github.com/coder/coder/v2 to v2.34.0-rc.0.0.20260827091847-26b9c8764f91, containing the promoted organization-scoped chat model APIs.

Coder 2.37 scopes chat models to organizations and serves the chat API under /api/v2. The old unscoped model-config API and codersdk.ChatModelConfig surface were replaced by organization-scoped chat models under /api/v2/organizations/{organization}/chats/models, and coder/coder#28632 removed the legacy unscoped /api/experimental/chats/models route entirely. This PR adapts coderd_agents_model and coderd_agents_system_prompt to the stable /api/v2 API, with no experimental-route fallbacks.

Breaking changes

coderd_agents_model and coderd_agents_system_prompt now require Coder v2.37.0 or later. Against an older server, plans and applies fail with a diagnostic naming the promoted endpoint and minimum version. Downgrade the provider if you need compatibility with older Coder releases.

coderd_agents_model gains an organization_id attribute. It is optional and defaults to the provider's default organization, where upstream migrated pre-2.37 chat models:

resource "coderd_agents_model" "sonnet" {
  organization_id = coderd_organization.eng.id
  # ...
}

Changing a configured organization_id forces replacement because models cannot move between organizations.

The import ID format changes from the model UUID to <organization-name>/<model-id> (the organization component also accepts a UUID):

terraform import coderd_agents_model.sonnet my-org/4c766bb0-0b48-4b55-9d7c-3f7c0116e78a

State written by earlier provider releases has no organization_id, and the compatibility route that could have recovered it was removed upstream. To upgrade, set organization_id in config and apply: the provider adopts the model in place (an update, not a replace), verifies the value against the organization-scoped API, and records it in state. Until then, refresh warns and skips, and updates or destroys fail with instructions.

What changed

  • CRUD uses the promoted organization-scoped /api/v2 endpoints; Read uses GET-by-ID instead of scanning the organization list.
  • organization_id is mapped from server responses and composite imports; legacy state without it is adopted in place from the configured value on the next apply.
  • An end-to-end test upgrades real pre-organization state (written by a schema without organization_id) and asserts adoption plans as an in-place update.
  • Endpoint 404s produce actionable diagnostics that distinguish unsupported Coder versions from missing or inaccessible organizations.
  • The existing create-conflict retry remains in place.
  • Acceptance tests probe for the promoted endpoints (chat models and system prompt) and skip when the target deployment predates them, because ghcr.io/coder/coder:latest and development builds can lag the promotion.
  • Container logs are dumped from a cleanup-safe context so failed integration tests keep their logs.
  • coderd_default_agents_model is mechanically adapted to the promoted SDK surface; feat!: add organization-scoped coderd_agents_default_model #423 replaces it with the organization-scoped coderd_agents_default_model resource.
Stack plan
  1. Scope coderd_agents_model to organizations and bump the Coder SDK (this PR).
  2. Replace coderd_default_agents_model with coderd_agents_default_model in feat!: add organization-scoped coderd_agents_default_model #423.

Disclosure: Xum (AI agent) authored this PR on @ethanndickson's behalf.

Relates to CODAGT-973

@ethanndickson
ethanndickson force-pushed the org-chat-models/agents-model branch from c615784 to 34faf9b Compare August 25, 2026 10:16
@ethanndickson ethanndickson changed the title feat!: scope coderd_agents_model to organizations DNM: feat!: scope coderd_agents_model to organizations Aug 25, 2026
@ethanndickson
ethanndickson marked this pull request as ready for review August 25, 2026 10:18

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 34faf9bf48

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/provider/agents_model_resource.go Outdated
Comment thread internal/provider/default_agents_model_resource.go
@linear-code

linear-code Bot commented Aug 25, 2026

Copy link
Copy Markdown

CODAGT-973

@ethanndickson

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 325b4cef3b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/provider/default_agents_model_resource.go
Comment thread integration/integration_test.go

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 852988f6c3

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ethanndickson
ethanndickson force-pushed the org-chat-models/agents-model branch from 852988f to 123b020 Compare August 25, 2026 16:44
@ethanndickson
ethanndickson requested a review from matifali August 26, 2026 08:50
@ethanndickson ethanndickson changed the title DNM: feat!: scope coderd_agents_model to organizations feat!: scope coderd_agents_model to organizations Aug 27, 2026

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b11a6a2cb2

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread integration/integration.go Outdated
…d route

The SDK now calls /api/v2/chats/config/system-prompt, first served in
Coder 2.37 (coder/coder#28496). Skip the real-Coder acceptance tests when
the deployment does not serve the endpoint, matching the chat model tests.
Coder 2.37 removed GET /api/experimental/chats/models
(coder/coder#28632), so organization_id can no longer be recovered from
state written by earlier provider versions. Error with re-import
instructions instead.
…tion_id

State written before models were organization-scoped lacks organization_id,
and Coder 2.37 removed the compatibility route that could recover it
(coder/coder#28632). Instead of forcing a state rm + re-import, let users set
organization_id in config: Read skips refresh on legacy state with a warning,
the plan modifier treats null-state adoption as an in-place update rather than
a replace, and Update falls back to the planned organization_id, which the
org-scoped PATCH verifies and the state write-back records permanently.
@matifali

Copy link
Copy Markdown
Member

Bumps github.com/coder/coder/v2 to v2.34.0-rc.0.0.20260827091847-26b9c8764f91, containing the promoted organization-scoped chat model APIs.

Will we bump this again to v2.37.0 after the release? We can wait to release the provider till then or make another release with that change.

@ethanndickson

Copy link
Copy Markdown
Member Author

Bumps github.com/coder/coder/v2 to v2.34.0-rc.0.0.20260827091847-26b9c8764f91, containing the promoted organization-scoped chat model APIs.

Will we bump this again to v2.37.0 after the release? We can wait to release the provider till then or make another release with that change.

Doesn't make a difference whether its pinned to a commit or a tag fortunately. as long as it has the code we want either is fine

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ed6183b993

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/provider/agents_model_resource.go
An organization_id that is unknown at plan time (e.g. a terraform_data
output) conservatively forces replacement, matching the framework's stock
RequiresReplaceIfConfigured semantics. Deferring on unknown instead would
downgrade a real organization move to an in-place update that PATCHes the
old organization. Prove the conservative plan lands correctly end-to-end:
the apply deletes the model from the prior organization and recreates it
in the resolved one.

Copy link
Copy Markdown
Member Author

@codex review

re: "Defer replacement while organization ID is unknown" (P1)

Intentional — and the suggested deferral would be strictly worse:

  • Unknown-forces-replacement matches the framework's stock stringplanmodifier.RequiresReplaceIfConfigured, which has no unknown guard either (its condition is identical: !ConfigValue.IsNull()). This is the standard conservative semantics of every built-in RequiresReplace* modifier.
  • Returning early on unknown makes the plan an in-place update. If the value then resolves to a different organization, Update PATCHes the old organization (state takes precedence in resolveOrganizationID, which is required for legacy-state adoption) and the configured move is silently ignored — trading a visible, conservative replace for a silent misapply.
  • A cross-organization move cannot be in-place anyway: chat model configs are per-organization rows server-side, so moving one is inherently destroy + create.
  • The unknown→replace decision was already asserted as intentional in TestAgentsModelOrganizationRequiresReplace ("unknown config" case). Added TestAgentsModelUnknownOrganizationReplacement (d70bf3c) proving the risky path end-to-end: an unknown organization_id resolving to a different org plans as Replace and the apply DELETEs from the old org and recreates in the new one. With the suggested deferral applied, that plan degrades to [update] and the test fails — so it also serves as a tripwire.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 👍

Reviewed commit: d70bf3ce33

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@ethanndickson
ethanndickson merged commit a58de1f into main Aug 31, 2026
13 checks passed
@ethanndickson
ethanndickson deleted the org-chat-models/agents-model branch August 31, 2026 10:19
ethanndickson added a commit that referenced this pull request Aug 31, 2026
Stacked on #422.

Coder 2.37 makes the default chat model per-organization rather than
deployment-global: each organization has its own default, the first
model created in an organization is automatically promoted, and existing
configurations are migrated to the default organization. The
experimental `coderd_default_agents_model` resource modeled one global
selection and no longer matches the server.

This PR replaces it with `coderd_agents_default_model`:

- Renames the resource from `coderd_default_agents_model` to
`coderd_agents_default_model`, grouping it with `coderd_agents_model`.
- Requires an explicit `organization_id`; changing it forces
replacement.
- Uses the organization UUID as the resource `id`, since each
organization has one default.
- Create and update mark the selected model as default through the
organization-scoped `/api/v2` endpoint.
- Read lists the organization's models and resolves its current default.
- Missing or inaccessible organizations and unsupported Coder versions
produce actionable diagnostics.
- Delete remains an intentional no-op because Coder requires a default
while models exist and provides no unset-default API.

## Breaking change and migration

`coderd_default_agents_model` is removed and replaced by
`coderd_agents_default_model`. The new resource implements
`ResourceWithMoveState`, allowing existing state to migrate
declaratively:

```hcl
moved {
  from = coderd_default_agents_model.this
  to   = coderd_agents_default_model.this
}

resource "coderd_agents_default_model" "this" {
  organization_id = var.organization_id
  model_id        = coderd_agents_model.default.id
}
```

The legacy deployment-wide selection is assigned to the provider's
default organization during the move. The configured `organization_id`
should therefore identify that same organization.

Also folds in the `coderd_agents_mcp_server` import ID change
(originally #427): `<organization-name>/<slug>` instead of
`<organization-id>/<id>` (the organization component also accepts a
UUID). Slugs are unique per organization, but the get-by-ID endpoint
only accepts UUIDs, so import resolves the slug from the organization's
server list.

The resource requires Coder v2.37.0 or later. Its import ID is the
organization name (a UUID is also accepted); `model_id` is resolved
during read.

> Disclosure: Xum (AI agent) authored this PR on @ethanndickson's
behalf.

Closes CODAGT-973
ethanndickson added a commit that referenced this pull request Aug 31, 2026
## Problem

All `coderd_*` resources and data sources render on the Terraform
Registry with an empty `subcategory`, so the sidebar lists every
resource/data source flat with no grouping.

## Fix

Add per-resource doc templates under
`templates/resources/<name>.md.tmpl` and
`templates/data-sources/<name>.md.tmpl` (the [tfplugindocs conventional
paths](https://github.com/hashicorp/terraform-plugin-docs#conventional-paths),
matching the pattern used by hashicorp/aws, azurerm, google). Each is a
copy of tfplugindocs' default template with a hardcoded `subcategory`,
grouping pages into:

- **Agents** — `agents_mcp_server`, `agents_model`,
`agents_system_prompt`, `agents_default_model`
- **AI Governance** — `ai_provider`
- **Deployment** — `license`, `oauth2_provider_settings`,
`provisioner_key`, `workspace_proxy`
- **Identity & Access Management** — `organization`,
`organization_group_sync`, `organization_sync_settings`, `group`, `user`
- **Templates** — `template`

The templates also drop the
`HasImportIDConfig`/`HasImportIdentityConfig` branches from
tfplugindocs' default template: no resource in this repo ships
`import-by-string-id.tf`/`import-by-identity.tf` example files, so those
branches were always-false dead code. Resource templates keep a single
`HasImport` (`terraform import`) section; data-source templates have no
import section (data sources are never imported).

Regenerated `docs/` with `make gen`; the diff against the base branch is
exactly the `subcategory` line per file (19 files), nothing else
changed.

## Stacking

Stacked on #423 (which stacks on #422). Covers the stack's org-scoped
`coderd_agents_default_model` rename (subcategory: Agents); the base
already includes the #425 `agents_system_prompt` rename.

## Note for future resources

With per-resource templates, a new resource/data source added without a
matching `templates/` file falls back to tfplugindocs' embedded default
(`subcategory: ""`) and renders uncategorized at the top of the sidebar.
Copy a sibling template and set the right subcategory when adding one.

## Testing

- `make build`, `make fmt`, and `make gen` (idempotent, no drift) are
all clean.
- `tfplugindocs validate --provider-name coderd` passes.
- `make lint` has 15 pre-existing `usetesting` findings, unchanged from
the base (verified via `git stash`); unrelated to this change.

---------

Co-authored-by: Ethan Dickson <ethan@coder.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants