GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — feat: add agent-plugins experiment and Agent API v2.16 plugin messages by jscottmiller · Pull Request #29320 · coder/coder

Conversation

@jscottmiller

@jscottmiller jscottmiller commented Sep 15, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Linear: CODAGT-1101

tl;dr: Adds the agent-plugins experiment and the Agent API v2.16 messages that carry Agent Plugins data from the agent to coderd. First of eight stacked PRs adding read-only Agent Plugins v1.0.0 support.

A plugin is a directory with a plugin.json manifest, skills under skills/, and an optional mcp.json. Across the stack, the agent discovers plugins in plugins/ and .agents/plugins/ under its scan roots (for example ~/.coder/plugins/<name>), chatd lists their skills with plugin attribution, the agent runs the MCP servers of plugins in the workspace working directory, and the Agents page shows plugin attribution in the chat context. Hooks, commands, agents, install flows, and org-managed plugins are out of scope. Background: research/agent-plugins-standard.md (internal).

This PR adds codersdk.ExperimentAgentPlugins and a PluginBody oneof variant on ContextResource (tag 18) that carries the validated manifest fields and nests the plugin's skills and MCP servers. Manifest gains agent_plugins_enabled (field 21), which coderd sets when the experiment is enabled; the agent discovers plugins only then. coderd stores each nested resource as its own row with the plugin's name in a new plugin_name column (migration 000633), which the hydrate, MCP sync, and re-pin queries copy. With the experiment off, PushContextState drops plugin resources and everything nested in them. Otherwise it rejects pushes with plugin names that fail workspacesdk.ValidatePluginName (the spec's name grammar, shared by agent and coderd), OK plugins without a name or with a duplicate name, a non-OK plugin that nests resources, nested entries of the wrong kind, plugin skill sources outside <plugin source>/skills/, and plugin MCP servers with an empty server_name or a source other than <plugin name>/<server_name>. Nested resources count toward the 1000-resource cap.

Agents now dial v2.16, so a new agent needs a coderd that supports it, as with every Agent API minor. Turning the experiment off does not remove plugin data already pinned to existing chats.

PR map

main..4b0cfc9657

Category Files + -
prod (backend) 15 342 78
test (backend) 9 534 3
migrations 2 14 0
generated (backend) 7 1216 1027
generated (frontend) 1 2 0
Total 34 2108 1108
  1. coderd/agentapi/context.go (+211/-51, API): drops plugin resources when the experiment is off; otherwise validates plugin names and nesting, and stores each nested skill and MCP server as its own row with the plugin's name.
  2. agent/proto/agent.proto (+39/-9, API): PluginBody with nested skills and mcp_servers, and Manifest.agent_plugins_enabled.
  3. codersdk/workspacesdk/frontmatter.go (+31/-0): ValidatePluginName and MaxPluginNameLength (manifest name grammar).
  4. coderd/database/queries/chats.sql, workspaceagentcontext.sql, migration 000633 (+28/-7, DB): the plugin_name column on both context resource tables, copied by the hydrate, MCP sync, and re-pin queries.
  5. codersdk/agentsdk/agentsdk.go, agent/agent.go (+18/-4, API): Manifest.AgentPluginsEnabled and ConnectRPC216WithRole; the agent dials v2.16.
  6. coderd/agentapi/api.go, manifest.go (+4): the manifest flag follows the experiment.
  7. tailnet/proto/version.go (+8/-1, API): Agent API v2.16.
  8. codersdk/deployment.go (+4, API): the agent-plugins experiment.

This PR was generated by Coder Agents on behalf of @jscottmiller.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@github-actions github-actions Bot assigned jscottmiller Sep 15, 2026
@jscottmiller
jscottmiller added this pull request to stack #29327 September 15, 2026 01:14
@jscottmiller jscottmiller added the experimental Changes that might not necessarily be merged, until its approved to proceed with. label Sep 15, 2026
This was referenced Sep 15, 2026
feat: discover and validate Agent Plugins manifests #29321
Closed
feat(coderd/x): add plugin skill source and alias grammar #29322
Closed
feat: serve plugin skills in chatd #29323
Closed
feat: accept streamable-http MCP type, add plugin data dir helper #29324
Closed
feat(agent/x/agentmcp): load plugin mcp.json with per-entry isolation #29325
Closed
feat: run plugin MCP servers discovered by agentcontext #29326
Closed
@jscottmiller jscottmiller changed the title scott/agent plugins/1 api feat: add agent-plugins experiment and Agent API v2.13 plugin messages Sep 15, 2026
@jscottmiller jscottmiller mentioned this pull request Sep 15, 2026
feat: add read-only support for Agent Plugins behind the agent-plugins experiment #29308
Closed
@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch 2 times, most recently from 931721d to 71f89e0 Compare September 15, 2026 17:53
@jscottmiller jscottmiller changed the title feat: add agent-plugins experiment and Agent API v2.13 plugin messages feat: add Agent API v2.13 plugin messages Sep 15, 2026
@jscottmiller jscottmiller removed the experimental Changes that might not necessarily be merged, until its approved to proceed with. label Sep 15, 2026
@linear-code

linear-code Bot commented Sep 22, 2026

Copy link
Copy Markdown

CODAGT-1101

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch from 71f89e0 to 815c273 Compare September 24, 2026 22:10
@jscottmiller jscottmiller changed the title feat: add Agent API v2.13 plugin messages feat: add agent-plugins experiment and Agent API v2.13 plugin messages Sep 24, 2026
@jscottmiller jscottmiller added the experimental Changes that might not necessarily be merged, until its approved to proceed with. label Sep 24, 2026
@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch from 815c273 to 961c9b5 Compare September 30, 2026 01:18
@jscottmiller jscottmiller removed the experimental Changes that might not necessarily be merged, until its approved to proceed with. label Sep 30, 2026
@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch from 961c9b5 to b500f10 Compare September 30, 2026 23:08
@jscottmiller

jscottmiller commented Oct 1, 2026

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

coder-agents-review[bot] reacted with rocket emoji
All reactions
  • 🚀 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@coder-agents-review

coder-agents-review Bot commented Oct 1, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Chat: Review posted | View chat
Requested: 2026-10-07 18:56 UTC by @jscottmiller

Review history
  • R1 (2026-10-01): 12 reviewers, 2 Nit, 7 P3, 8 P4, COMMENT. Review
  • R2 (2026-10-02): 13 reviewers, 3 Nit, 9 P3, 12 P4, COMMENT. Review
  • R3 (2026-10-02): 11 reviewers, 5 Nit, 12 P3, 16 P4, COMMENT. Review
  • R4 (2026-10-03): 12 reviewers, 8 Nit, 12 P3, 18 P4, COMMENT. Review
  • R5 (2026-10-03): 11 reviewers, 10 Nit, 13 P3, 24 P4, COMMENT. Review
  • R6 (2026-10-06): 12 reviewers, 11 Nit, 14 P3, 32 P4, COMMENT. Review
  • R7 (2026-10-06): 13 reviewers, 12 Nit, 17 P3, 39 P4, COMMENT. Review
  • R8 (2026-10-06): 13 reviewers, 15 Nit, 19 P3, 45 P4, COMMENT. Review
  • R9 (2026-10-07): 14 reviewers, 17 Nit, 19 P3, 53 P4, COMMENT. Review

deep-review v0.13.0 | Round 9 | b4fb790..ff177d1

Last posted: Round 9, 89 findings (19 P3, 53 P4, 17 Nit), COMMENT. Review

Finding inventory

Finding inventory: PR #29320

Findings

# Sev Status Location Summary Round Reviewer Posted
CRF-1 P3 Author fixed (10dbcb0) coderd/x/chatd/context_prompt.go:403 chatd doc comments still call plugin kind "reserved" R1 Netero Yes
CRF-2 P4 Author fixed (10dbcb0) coderd/database/dump.sql:3576 body_kind column comments still say plugin reserved for Claude Code RFC R1 Netero Yes
CRF-3 P4 Author fixed (10dbcb0) codersdk/workspacesdk/frontmatter.go:26 ValidatePluginName has no caller; coderd stores unvalidated names R1 Netero Yes
CRF-4 P4 Author fixed (2be2785) codersdk/agentsdk/agentsdk.go:371 ConnectRPC213WithRole and DRPCAgentClient213 unused R1 Netero Yes
CRF-5 P4 Author fixed (10dbcb0) codersdk/agentsdk/convert.go:70 No round-trip test for PluginsSupported R1 Netero Yes
CRF-6 Note Note (body) agent/agent.go:1183 PR description says agents dial v2.10; they dial v2.11 R1 Netero No
CRF-7 Note Note (body) CI gen/offlinedocs failures come from base commit R1 Netero No
CRF-8 P3 Author fixed (10dbcb0) coderd/agentapi/context.go:396 PushContextState stores plugin data with experiment off; gate enforced only by agent R1 Melody P3, Ryosuke P3, Kurapika P3, Mafuuu P4, Pariston Note, Mafu-san Note Yes
CRF-9 P3 Author fixed (10dbcb0) agent/proto/agent.proto:558 ContextResource comment omits plugin kind and drops the unknown-variant rejects-whole-push constraint R1 Gon P2, Mafuuu P4, Leorio P4, Melody Nit Yes
CRF-10 P3 Author fixed (10dbcb0) codersdk/agentsdk/agentsdk.go:138 PluginsSupported doc states a false condition and omits the agent contract R1 Gon P2, Leorio P3 Yes
CRF-11 P3 Author contested; panel closed R2 (1/1 accept) agent/proto/agent.proto:107 plugins_supported names a capability but carries experiment state R1 Gon Yes
CRF-12 P4 Author fixed (10dbcb0) agent/proto/agent_drpc_old.go:109 DRPCAgentClient212 comment lists one of two v2.12 changes R1 Gon P3, Leorio P4 Yes
CRF-13 P3 Author fixed (10dbcb0) codersdk/workspacesdk/frontmatter.go:39 Invalid-character error names wrong byte for non-ASCII and omits allowed set R1 Leorio P3, Ging-go P4, Chopper P4 Yes
CRF-14 P3 Author fixed (10dbcb0) coderd/agentapi/api.go:159 No test covers Experiments wiring from Options into ManifestAPI R1 Bisky Yes
CRF-15 P4 Dropped by orchestrator (matches four sibling arms; whole-switch cleanup listed out of scope as CRF-25) coderd/agentapi/context.go:398 Dead nil-payload guard in plugin arm R1 Bisky No
CRF-16 P4 Author fixed (10dbcb0) codersdk/workspacesdk/frontmatter_test.go:198 Valid table lacks mixed separators and spec examples R1 Bisky Yes
CRF-17 P4 Dropped by orchestrator (disproved: TestGetManifest/OK/Child asserts false; verified by Bisky, Chopper, Mafu-san, Netero) coderd/agentapi/manifest_test.go:329 No test asserts PluginsSupported false R1 Ryosuke No
CRF-18 P4 Author contested; panel closed R2 (6/6 accept) codersdk/deployment.go:5519 Experiment description promises behavior this PR does not ship R1 Mafu-san P4, Ryosuke Note, Mafuuu Note, Gon Note, Leorio Note, Chopper Note Yes
CRF-19 P4 Author fixed (10dbcb0) agent/proto/agent.proto:656 source comment does not define plugin root or plugin MCP server source format; same-name servers collide on PK R1 Knuckle, Gon (OOS item merged) Yes
CRF-20 Note Note (body) coderd/database/queries/chats.sql:1684 Plugin rows re-pin only on drift, so pinned plugin_name may reference an unpinned plugin row R1 Knuckle No
CRF-21 Nit Author fixed (10dbcb0) agent/agentcontext/resolve.go:842 KindPlugin still documented as Claude Code plugin manifests R1 Mafuuu Yes
CRF-22 Nit Author fixed (10dbcb0) codersdk/workspacesdk/frontmatter.go:25 Doc comment hardcodes 64 next to MaxPluginNameLength R1 Gon Yes
CRF-23 Nit Dropped by orchestrator (squash merge uses PR title and body, not the commit body) commit b500f10 Commit body line is 110 characters R1 Leorio No
CRF-24 OOS Out of scope (body) coderd/x/chatd/context_prompt.go:115 MCP tool names built from server_name collide across plugins R1 Knuckle No
CRF-25 OOS Out of scope (body) coderd/agentapi/context.go:368-394 Unreachable nil-payload guards in existing switch arms R1 Bisky No
CRF-26 P3 Author fixed (2be2785) coderd/agentapi/context.go:390 OK plugin resource with empty name is stored; comment claims only non-OK may be empty R2 Gon P3, Bisky P3, Ryosuke P4, Leorio P4, Zoro P4 Yes
CRF-27 P3 Author fixed (2be2785) coderd/agentapi/api.go:289 No test covers Experiments wiring into ContextAPI R2 Bisky Yes
CRF-28 P4 Author fixed (2be2785) agent/proto/agent.proto:558 Wire contract does not say an invalid plugin name rejects the whole snapshot R2 Mafuuu P4, Chopper Note Yes
CRF-29 P4 Author fixed (2be2785) agent/proto/agent.proto:566 Plugin MCP source format can collide with a workspace .mcp.json server name containing "/" R2 Knuckle Yes
CRF-30 Nit Author fixed (2be2785) coderd/agentapi/context.go:400 isPlugin closure also matches plugin-attributed skills and servers R2 Gon Yes
CRF-31 P4 Author fixed (2be2785) coderd/agentapi/context.go:387 validateContextPluginName is a single-caller wrapper R2 Zoro Yes
CRF-32 P4 Author fixed (2be2785) coderd/agentapi/context.go:406 ContainsFunc fast path in withoutPluginResources is unmeasured R2 Zoro Yes
CRF-33 Note Note (body) coderd/agentapi/context.go:83 With experiment off, stored aggregate hash covers dropped plugin resources (documented) R2 Melody, Knuckle, Ryosuke No
CRF-34 Note Note (body) commit 10dbcb0 Commit body still says v2.10 and no migration; squash uses PR body R2 Mafu-san No
CRF-35 P3 Author fixed (825f9e6) coderd/agentapi/context.go:421 withoutShadowedPluginServers adds a coderd-side collision policy that the agent should own R3 Ryosuke P3, Zoro P3 Yes
CRF-36 P4 Author fixed (825f9e6) coderd/agentapi/context.go:433 Shadowed plugin MCP server is dropped with no log, row, or error R3 Chopper P4, Leorio P4, Mafuuu P4, Knuckle P4 Yes
CRF-37 P4 Author fixed (825f9e6) coderd/agentapi/context.go:137 Shadow drop runs before validation, so malformed plugin servers are dropped instead of rejected R3 Bisky P4, Mafuuu P4 Yes
CRF-38 P3 Author fixed (825f9e6) coderd/agentapi/context.go:405 No test stores a valid plugin MCP server with the experiment on R3 Bisky Yes
CRF-39 P3 Author fixed (825f9e6) agent/proto/agent.proto:641 OK plugin names are not required unique per push, so plugin_name is ambiguous R3 Mafuuu P3, Knov P4 Yes
CRF-40 P4 Author fixed (825f9e6) coderd/agentapi/context.go:418 withoutShadowedPluginServers doc says "another resource"; plugin-plugin collisions still fail the push R3 Gon P3, Netero Note Yes
CRF-41 P4 Author fixed (825f9e6) coderd/agentapi/context.go:391 "(non-OK ones may not)" reads as a prohibition; bullets duplicate the list at :294-296 R3 Gon P2, Leorio Nit, Zoro Nit Yes
CRF-42 Nit Author fixed (825f9e6) coderd/agentapi/context.go:412 isPluginMCPServer comment restates the one-line body R3 Gon P2 Yes
CRF-43 Nit Author fixed (825f9e6) coderd/agentapi/context.go:422 Map name other does not say what it holds R3 Gon Yes
CRF-44 Note Note (body) agent/proto/agent.proto:631 Proto says invalid plugin_name rejects the push, but with experiment off the resource is dropped R3 Melody No
CRF-45 Note Dropped by orchestrator (shadow drop removed in 825f9e6) coderd/agentapi/context.go:83 With experiment on, the stored aggregate hash also covers shadow-dropped servers R3 Knuckle No
CRF-46 OOS Out of scope (body) agent/x/agentmcp/manager.go:711 Agent MCP server map and chatd routing key on bare server_name, so plugin and workspace servers with the same server_name collide R3 Melody No
CRF-47 P4 Author fixed (938caef) coderd/agentapi/context.go:343 Duplicate OK plugin name error omits the first plugin's source R4 Chopper, Leorio, Mafuuu Yes
CRF-48 P4 Author fixed (938caef) coderd/agentapi/context.go:342 plugin_name need not reference an OK plugin in the push R4 Knov P4, Meruem P4, Ryosuke Note, Zoro Note Yes
CRF-49 Nit Author fixed (938caef) agent/proto/agent.proto:633 PluginBody comment repeats the source contract from ContextResource.source R4 Gon P2 Yes
CRF-50 Nit Author fixed (938caef) coderd/agentapi/context.go:421 withoutPluginResources also drops plugin-attributed resources; rename to withoutPluginData R4 Gon Yes
CRF-51 Nit Author fixed (938caef) coderd/agentapi/context_test.go:486 RejectsInvalidPluginName contains cases without an invalid name R4 Gon Yes
CRF-52 P2 Dropped by orchestrator (author applied one of the two fixes CRF-41 offered; helper list matches helper checks) coderd/agentapi/context.go:394 Helper doc list duplicates caller's list R4 Gon No
CRF-53 P2 Dropped by orchestrator (comment maps each kind to its field; no behavior consequence) coderd/agentapi/context.go:379 contextPluginName doc restates switch R4 Gon No
CRF-54 Nit Dropped by orchestrator (uppercase carried over from the base comment text) coderd/database/migrations/000612_context_resources_plugin_comments.up.sql:3 HOOK/SUBAGENT/COMMAND case in comment R4 Gon No
CRF-55 Note Note (body) agent/proto/agent.proto:562 Removing the shadow drop makes a workspace server named / fail the whole push; agent PR must resolve it R4 Leorio, Chopper, Mafuuu, Knuckle, Melody No
CRF-56 OOS Out of scope (body) agent/agentcontext/push.go:120 pushWithRetry resends a deterministically rejected push forever R4 Chopper No
CRF-57 OOS Out of scope (body) coderd/agentapi/context_test.go Tests use context.Background() instead of t.Context() (existing file pattern) R4 Ging-go No
CRF-58 P3 Author fixed (8397708) coderd/agentapi/context.go:364 Orphan skip runs before body, size, and status checks, so malformed orphans are accepted R5 Mafuuu P4, Knov P4, Meruem P4, Chopper P4, Bisky P4, Razor P4 Yes
CRF-59 P4 Author fixed (8397708) coderd/agentapi/context.go:325 First pass reports duplicate plugin name before duplicate or empty source checks R5 Melody, Mafuuu Yes
CRF-60 P4 Author fixed (8397708) coderd/agentapi/context.go:366 plugin_name matched by name only, so a non-OK plugin's skill is attributed to an OK plugin of the same name R5 Melody P4, Meruem Note, Ryosuke Note Yes
CRF-61 P4 Author fixed (8397708) coderd/agentapi/context_test.go:611 No test asserts the orphaned sources or the warning R5 Bisky, Chopper Yes
CRF-62 P4 Author fixed (8397708) coderd/agentapi/context_test.go:601 Orphan test orders plugins before skills, so first-pass order independence is untested R5 Bisky Yes
CRF-63 P4 Author fixed (8397708) coderd/agentapi/context.go:145 Warning text wrong for an absent plugin; the skip has four different names R5 Leorio P4, Gon Nit Yes
CRF-64 P4 Author fixed (8397708) agent/proto/agent.proto:636 Orphan rule is documented on PluginBody, not on the plugin_name fields it applies to R5 Gon Yes
CRF-65 Nit Author fixed (8397708) coderd/agentapi/context.go:305 "A valid skill or MCP server" reads as status OK, but the skip ignores status R5 Gon P2 Yes
CRF-66 Nit Author fixed (8397708) coderd/agentapi/context.go:316 okPlugins comment restates the assignment; rename to okPluginSources R5 Gon P2 Yes
CRF-67 Note Note (body) coderd/agentapi/context.go:145 Orphan warning logs before the version gate and carries no version field R5 Chopper No
CRF-68 Note Note (body) coderd/agentapi/context.go:140 With experiment on, stored aggregate hash covers orphan-skipped resources R5 Netero No
CRF-69 P4 Author fixed (4494299) coderd/agentapi/context.go:453 plugin_source byte cap rejects the push for input the skip already discards R6 Netero Yes
CRF-70 P4 Author fixed (4494299) tailnet/proto/version.go:95 v2.13 changelog omits plugin_source R6 Netero Yes
CRF-71 P4 Author fixed (4494299) PR description Description still describes the name-only skip rule and omits plugin_source R6 Netero Yes
CRF-72 P3 Author fixed (4494299) agent/proto/agent.proto:672 Shadowed same-name plugin with the same server_name yields duplicate source acme/echo and rejects the push before the skip R6 Mafuuu P3, Knov P3, Bisky P3, Razor P3, Melody P3, Ryosuke P3, Meruem P4 Yes
CRF-73 P4 Author fixed (4494299) coderd/agentapi/context.go:388 Skill plugin_source not checked against the skill's own source R6 Knov Yes
CRF-74 P4 Author fixed (4494299) coderd/agentapi/context.go:145 Skip warning logs only sources, not plugin_name and plugin_source R6 Chopper Yes
CRF-75 P4 Author fixed (4494299) coderd/agentapi/context.go:451 Pairing error does not say which field is set R6 Leorio Yes
CRF-76 P4 Author fixed (4494299) coderd/agentapi/context.go:306 Skip rule wording (Go doc and both plugin_source comments) reads as skipping every non-plugin resource R6 Gon Yes
CRF-77 Nit Author fixed (4494299) coderd/agentapi/context_test.go:1046 withSkillPlugin/withServerPlugin comments restate the body R6 Gon P2 Yes
CRF-78 P4 Author fixed (4494299) coderd/agentapi/context.go:479 Experiment off: resources with only plugin_source are rejected instead of dropped R6 Ryosuke Yes
CRF-79 P4 Author fixed (f64e456) coderd/agentapi/context.go:83 ContextAPI.Experiments comment omits source-only drop R7 Netero Yes
CRF-80 P4 Author fixed (f64e456) agent/proto/agent.proto:634 Proto skill prefix rule omits the accepted backslash form R7 Netero Yes
CRF-81 P3 Author fixed (f64e456) coderd/agentapi/context.go:396 Uncapped MCP server plugin_source is logged in the skip warning and quoted in errors (multi-MB lines) R7 Kurapika P3, Knov P4, Razor P4, Chopper P4 Yes
CRF-82 P3 Author fixed (f64e456) agent/proto/agent.proto:103 plugins_supported contract is not per connection; process-wide snapshot can reach an older coderd on reconnect R7 Meruem Yes
CRF-83 P3 Author fixed (f64e456) agent/proto/agent.proto:638 plugin_source duplicates okPluginSources now that agents send only OK plugin children R7 Zoro Yes
CRF-84 P4 Author fixed (f64e456) coderd/agentapi/context.go:389 Skip is a second failure policy for a contract violation that rejects elsewhere R7 Zoro Yes
CRF-85 P4 Author fixed (f64e456) coderd/agentapi/context.go:471 Backslash prefix branch has only an accept test R7 Bisky Yes
CRF-86 P4 Author fixed (f64e456) coderd/agentapi/context.go:485 Plugin MCP server with empty server_name is accepted with source "/" R7 Ryosuke Yes
CRF-87 P4 Author fixed (f64e456) coderd/agentapi/context.go:309 PR description keeps the unscoped skip-rule sentence CRF-76 fixed in code R7 Leorio Yes
CRF-88 P4 Author fixed (f64e456) agent/proto/agent.proto:679 MCPServerBody.plugin_source last sentences do not state when the collision happens or that the rule is mandatory R7 Gon Yes
CRF-89 Nit Author fixed (f64e456) coderd/agentapi/context_test.go:640 NonOKPluginServerSharingOKServerSource sits under a subtest about duplicate names R7 Gon Yes
CRF-90 Note Note (body) agent/proto/agent.proto:624 Contract does not say whether plugin skill names must be unique against workspace skills; chatd findSkill returns the first match R7 Mafuuu No
CRF-91 Note Note (body) coderd/agentapi/context.go:469 skills/ prefix check is a raw string match, not path containment R7 Kurapika No
CRF-92 P4 Author fixed (ff177d1) codersdk/agentsdk/agentsdk.go:138 SDK PluginsSupported comment lacks the per-connection rule R8 Netero Yes
CRF-93 P3 Author fixed (ff177d1) coderd/agentapi/context.go:360 Plugin validation errors still quote uncapped plugin names, server_name, and unvalidated plugin sources R8 Leorio P3, Kurapika P4, Razor P4, Chopper P4, Meruem P4, Kite P4 Yes
CRF-94 P4 Author fixed (ff177d1) coderd/agentapi/context.go:310 With two OK plugins sharing a name, a skill of the second gets a path error instead of the duplicate-name error R8 Razor Yes
CRF-95 P4 Author fixed (ff177d1) agent/proto/agent.proto:674 OK-plugins-only rule sits only on MCPServerBody, its reason is server-only, and the same-server_name rejection is no longer stated R8 Gon P2, Razor P4, Ryosuke P4 Yes
CRF-96 P3 Author fixed (ff177d1) agent/proto/agent.proto:104 plugins_supported rule uses undefined terms; version.go gates only plugin resources, not plugin_name R8 Gon P3, Leorio P4 Yes
CRF-97 P4 Author fixed (ff177d1) coderd/agentapi/context.go:139 Experiment off: index-based errors use the filtered slice index R8 Bisky, Melody Yes
CRF-98 P4 Author fixed (ff177d1) coderd/agentapi/context.go:467 isPluginData plugin-body branch untested (nameless non-OK plugin) R8 Bisky Yes
CRF-99 P4 Author fixed (ff177d1) coderd/agentapi/context.go:341 Duplicate OK name check lives in the caller while other plugin rules live in validateContextPluginFields R8 Zoro Yes
CRF-100 Nit Author fixed (ff177d1) coderd/agentapi/context_test.go:530 Three accept subtests repeat setup; one table would do R8 Zoro P4 Yes
CRF-101 Nit Author fixed (ff177d1) coderd/agentapi/context_test.go:494 Cases Plugin/Skill/MCP do not say what is invalid R8 Gon Yes
CRF-102 Nit Author fixed (ff177d1) agent/proto/agent.proto:560 "snapshot" vs "push" for the same rejection R8 Gon Yes
CRF-103 Note Note (body) coderd/agentapi/context.go:440 Separator normalization accepts mixed-separator skill sources R8 Meruem No
CRF-104 OOS Out of scope (body) agent/agentcontext/resolve.go:636 Skill name error quotes up to 64 KiB, exceeding the 4096-byte Error cap R8 Kurapika No
CRF-105 P4 Open coderd/database/migrations/000614_context_resources_plugin_comments.up.sql:1 PR description names migration 000612 and v2.11 after the rebase R9 Netero Yes
CRF-106 P4 Open agent/proto/agent.proto:648 PluginBody non-OK paragraph omits nameless non-OK children and describes a server check coderd does not make R9 Gon P2, Razor P4 Yes
CRF-107 P4 Open agent/proto/agent.proto:648 No test asserts either documented outcome for servers of a non-OK plugin R9 Melody Yes
CRF-108 P4 Open coderd/agentapi/context.go:414 collectOKPlugins indexes unvalidated plugins, so errors depend on resource order and name the wrong resource R9 Meruem, Ryosuke Yes
CRF-109 P4 Open coderd/agentapi/context.go:474 MCP source error prints a template and drops the validated plugin name R9 Leorio Yes
CRF-110 Nit Open coderd/agentapi/context.go:453 Errors write status as "ok" instead of "OK" R9 Leorio Yes
CRF-111 Nit Open coderd/agentapi/context.go:300 "Error indexes refer to resources as sent" restates the loop R9 Gon P2 Yes
CRF-112 P4 Open coderd/agentapi/context.go:408 collectOKPlugins comment says the size filter is safe, not that it is required R9 Gon Yes
CRF-113 P4 Open coderd/agentapi/context_test.go:510 huge length and 4096 bound are unexplained literals with a hidden range constraint R9 Gon Yes
CRF-114 P4 Open coderd/agentapi/context_test.go:633 EmptySource row passes without the duplicate-name logic R9 Bisky Yes

Contested and acknowledged

CRF-11 (P3, agent/proto/agent.proto:107) - plugins_supported name vs experiment state

  • Finding: plugins_supported names a capability, but its value is the experiment state; a v2.13 coderd with the experiment off stored plugin resources yet sent false. Proposed renaming to plugins_enabled before release.
  • Author defense: coderd now drops plugin resources and plugin_name data when the experiment is off (CRF-8 fix), so false means this coderd will not store plugin data. That is the condition the finding itself said would make the current name accurate. The proto comment is now one condition. Name kept.
  • Panel closure (R2, 1/1): Gon, the agent that raised it (same agent, resumed), verified PushContextState drops plugin data with the experiment off (context.go:136-139, DropsPluginDataWithoutExperiment passes), so false now means coderd will not store plugin data, matching the name.

CRF-18 (P4, codersdk/deployment.go:5519) - experiment description promises unshipped behavior

  • Finding: The ExperimentAgentPlugins description says plugin skills appear in chats and plugin MCP servers run, but at this head enabling it only sets Manifest.plugins_supported. Proposed describing what this PR does, or adding the constant in the PR that adds agent discovery.
  • Author defense: The seven PRs land as one stack behind the experiment; the description is what operators see once the stack is in. The experiment is off by default and not in ExperimentsSafe, so a partial release exposes nothing unless someone opts in.
  • Panel closure (R2, 6/6): Mafu-san, Ryosuke, Mafuuu, Gon, Leorio, Chopper (each the agent that raised it, resumed) accepted. Consequence of the defended text: on a release cut mid-stack, an operator who opts in by name sees no behavior change and no error. Accepted because the experiment is off by default and absent from ExperimentsSafe, and enabling it at this head only sets a manifest flag.

CRF-4 (P4, agent/proto/agent_drpc_old.go:117) - unused 2.12/2.13 client interfaces

  • Finding: ConnectRPC213WithRole and DRPCAgentClient213 have no caller.
  • Author defense: Removed ConnectRPC213WithRole; kept DRPCAgentClient213 to match the convention that main defines DRPCAgentClient212 with no ConnectRPC212.
  • Panel re-raised (R2): Netero (new agent; the R1 Netero agent was not resumed because Netero ran as the first pass before the dispute check-in) re-raised. Orchestrator verified: on base 0f78361 and origin/main, agent_drpc_old.go ends at DRPCAgentClient211, and every interface 2.0 to 2.11 has a ConnectRPC2x caller. The PR adds DRPCAgentClient212, so the convention claim is not supported.

Law analysis

Not run. Effective additions 168 (threshold 1000).

Round log

Round 1

Full panel (round 1). Netero first pass: 1 P3, 4 P4, 2 Note, no P0, panel proceeded. Panel: ging-go, melody, ryosuke, knuckle, kurapika, pariston, mafuuu, bisky, gon, leorio, mafu-san, chopper (wildcard). Size 12: multi-domain (proto wire format, Go, coderd ingress of agent-supplied data). Result: 7 P3, 8 P4, 2 Nit, 3 Note (body), 2 OOS, 3 dropped. CRF-9 and CRF-10 downgraded from Gon P2 to P3: comment-only, the consequence depends on a future change. Keep-argument recorded: next developer adding a variant without a gate breaks every context push on older coderd. CRF-12 set to P4: the interface has no methods and version.go holds the full changelog. Reviewed against 0d12256..b500f10.

Round 2

Restructure round (new migration files 000612 added; effective additions 168 to 357). Churn guard PROCEED: 15 fixed, CRF-11 and CRF-18 contested; CRF-4 defense re-raised by Netero after orchestrator found its convention claim unsupported. Dispute check-in: gon, mafu-san, ryosuke, mafuuu, leorio, chopper resumed from R1 agents. CRF-11 closed 1/1, CRF-18 closed 6/6. Full panel: ging-go, melody, ryosuke, knuckle, kurapika, pariston, mafuuu, bisky, gon, leorio, mafu-san, chopper, plus wildcard zoro (13; chopper is a contested persona, outside the size target). Netero R2 is a new agent. New: 2 P3, 4 P4, 1 Nit, 2 Note (body). Reviewed against 0f78361..10dbcb0.

Round 3

Fix round (no files added; effective additions 357 to 489; changes address R2 findings). Churn guard PROCEED: 8 fixed (CRF-4, CRF-26 to CRF-32), none contested. Panel (new agents): gon, bisky, ryosuke, leorio, zoro, mafuuu, chopper, knuckle (raisers of findings whose code changed), ging-go, melody (specialists for changed Go and proto wire files), wildcard knov. New: 3 P3, 4 P4, 2 Nit; 2 Note (body), 1 OOS. Melody's routing-name P3 moved to out of scope (consumers in unchanged chatd and agent code; extends CRF-24). Gon P2 comment findings downgraded: CRF-41 to P4 (wording ambiguity, code is correct), CRF-42 to Nit; keep-argument recorded: duplicated rule lists drift. Most new findings come from the CRF-29 fix (withoutShadowedPluginServers). Reviewed against 0f78361..2be2785.

Round 4

Fix round (4 files changed; no files added; effective additions unchanged at 489). Churn guard PROCEED: CRF-35 to CRF-43 fixed. Panel (new agents): ryosuke, zoro, chopper, leorio, mafuuu, knuckle, bisky, knov, gon (raisers), ging-go, melody (specialists), wildcard meruem. New: 2 P4, 3 Nit, 1 Note (body), 2 OOS; 3 Gon findings dropped (CRF-52 keep-argument: two rule lists can drift; dropped because the author applied the fix offered and each list matches its function). Gon P2 on PluginBody downgraded to Nit (comment duplication, no behavior). Reviewed against 0f78361..825f9e6.

Round 5

Fix round (branch squashed; diff 825f9e6..938caef touches 4 files, no files added). Churn guard PROCEED: CRF-47 to CRF-51 fixed. Panel (new agents): chopper, leorio, mafuuu, knov, meruem, gon (raisers), ging-go, melody (specialists), ryosuke, bisky (policy layering and new tests), wildcard razor. New: 1 P3, 7 P4, 2 Nit, 2 Note (body). CRF-58 raised from six P4s to P3: consequence chain with CRF-56 (a malformed orphan is accepted, then fixing the manifest makes the same push reject, and the agent retry loop stops context sync until restart). Gon P2s on comments downgraded to Nit (wording, no behavior). Reviewed against 0f78361..938caef.

Round 6

Fix round (diff 938caef..8397708 touches 4 files; adds proto field plugin_source tag 5 as part of the CRF-60 fix; effective additions 577 to 758). Churn guard PROCEED: CRF-58 to CRF-66 fixed. Netero (advisory): 3 P4. Panel (new agents): mafuuu, knov, meruem, chopper, bisky, razor, melody, leorio, gon, ryosuke (raisers), ging-go (specialist), wildcard kite. New: 1 P3 (seven reviewers converged, reproduced), 8 P4, 1 Nit. CRF-71 (PR description) has no file line; listed in the review body. Gon P2 on test-helper comments downgraded to Nit. Reviewed against 0f78361..8397708.

Correction: CRF-71 was posted as an inline comment on tailnet/proto/version.go:95 (post requires every open finding inline), not in the review body.

Round 7

Fix round (diff 8397708..4494299; no files added). Churn guard PROCEED: CRF-69 to CRF-78 fixed. Netero advisory: 2 P4, 1 Note (not posted: fixture style). Panel (new agents): mafuuu, knov, meruem, chopper, bisky, razor, melody, ryosuke, leorio, gon (raisers), ging-go, kurapika (specialists: input bounds, path prefix), wildcard zoro. New: 3 P3, 7 P4, 1 Nit, 2 Note (body). CRF-81 is a fix-chain regression: the CRF-69 cap removal (our round-6 advice) plus the CRF-74 log fields left plugin_source unbounded; convergence of four reviewers set P3 (amplification runs before the version gate). CRF-83 (structural: delete plugin_source) would also remove CRF-81 and CRF-84. Meruem's push.go:150 out-of-scope item is CRF-56, not re-added. Reviewed against 0f78361..4494299.

Round 8

Fix round (diff 4494299..f64e456; plugin_source removed, skip replaced by rejection; effective additions 831 to 661). Churn guard PROCEED: CRF-79 to CRF-89 fixed. Netero advisory: 1 P4. Panel (new agents): kurapika, knov, razor, chopper, meruem, zoro, bisky, ryosuke, leorio, gon (raisers), ging-go, melody (specialists), wildcard kite. New: 2 P3, 7 P4, 3 Nit, 1 Note (body), 1 OOS. CRF-93 is the remaining half of CRF-81 (other uncapped fields reach errors), six reviewers, P3. Gon P2 on proto wording merged into CRF-95 at P4. Zoro P4 on test duplication downgraded to Nit. Reviewed against 0f78361..f64e456.

Round 9

Fix round (branch rebased onto b4fb790; migration renumbered to 000614; withoutPluginData replaced by in-loop drop; collectOKPlugins added). Churn guard PROCEED: CRF-92 to CRF-102 fixed. Netero advisory: 1 P4, 1 Note (DRPCAgentClient213 belongs in agent PR; not posted). Panel (new agents): leorio, kurapika, razor, chopper, meruem, kite, gon, bisky, melody, zoro, ryosuke (raisers), ging-go, knuckle (specialists; migration renumbered), wildcard takumi (distilled set exhausted). New: 8 P4, 2 Nit. No P3: CRF-93 bound verified by five reviewers and a <4096 test. Gon P2s downgraded (comment wording): CRF-106 merged with Razor at P4, CRF-111 to Nit; CRF-113 merges two Gon P4s. Reviewed against b4fb790..ff177d1.

About deep-review

CRF = Coder Review Finding (P0-P4, Nit, Note)

Reviewer Focus
Bisky tests
Chopper ops/errors
Churn-guard change verification
Ging language modernization
Gon naming
Hisoka edge cases
Killua perf
Kite change integrity
Knov contracts
Knuckle SQL
Komugi flake/determinism
Kurapika security
Law decomposition
Leorio docs
Luffy product
Mafu-san process
Mafuuu contracts
Melody dispatch/pairing
Meruem structural
Nami frontend
Netero mechanical checks
Pariston premise testing
Pen-botter product gaps
Razor verification
Robin duplication
Ryosuke Go arch
Takumi concurrency
Zoro shape

🤖 Managed by Coder Agents.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

coder-agents-review[bot]
coder-agents-review Bot reviewed Oct 1, 2026
View reviewed changes

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

This PR adds the agent-plugins experiment, the v2.13 plugin context messages, and Manifest.plugins_supported. Findings: 7 P3, 8 P4, 2 Nit.

The main design question is where the experiment is enforced. GetManifest gates plugins_supported on the experiment, but PushContextState stores plugin bodies and plugin_name values unconditionally and does not call ValidatePluginName, so both the experiment and the name grammar depend on the agent. Several comment findings below change wording depending on that answer.

Out of scope (needs a ticket or explicit acceptance by a human):

  • coderd/x/chatd/context_prompt.go:115: pinned MCP tool names are built as server + "__" + tool from server_name, so two plugins that declare the same server name produce identical model-facing tool names even when their sources differ (not checked against the later stack PRs).
  • coderd/agentapi/context.go:368-394: the four existing switch arms repeat a nil-payload guard that cannot change the stored body, since protojson.Marshal on a typed nil returns {}. The new plugin arm copies it.

Notes:

  • The PR description says agents keep dialing v2.10; agent/agent.go:1183 dials v2.11 through ConnectRPC211WithRole.
  • CI gen and offlinedocs fail because the base commit lacks docs/manifest/generated/cli.json; rebasing onto main fixes both. agent.pb.go regenerates without changes. The Storybook failure was not investigated because the job log could not be read.
  • coderd/database/queries/chats.sql:1684: mcp_server rows are re-synced into chat pins on every push, but plugin rows change only on a drift re-pin, so a pinned server's plugin_name can name a plugin that is not pinned or is pinned at an older version.

coderd/x/chatd/context_prompt.go:403

P3 [CRF-1] The contextResourceKind and pinnedContextResources (line 335) doc comments still call plugin a reserved kind. (Netero)

After the new ContextResource_Plugin arm in coderd/agentapi/context.go, plugin rows are written to workspace_agent_context_resources and pinned into chat_context_resources, and chatd drops them because it does not handle them yet. Change both comments to say plugin rows are stored but not surfaced, and that hook, subagent, and command remain reserved.

🤖

coderd/database/dump.sql:3576

P4 [CRF-2] The body_kind column comments on workspace_agent_context_resources and chat_context_resources (line 1930) still say plugin is reserved for the Claude Code plugin RFC. (Netero)

After this PR, plugin holds Agent Plugins PluginBody JSON. The enum needs no migration, but the column comments can only be corrected with a COMMENT ON COLUMN migration, in this PR or the stacked PR that first reads plugin rows.

🤖

agent/agentcontext/resolve.go:842

Nit [CRF-21] KindPlugin is still documented as "reserved for Claude Code plugin manifests", while this PR defines the plugin kind as an Agent Plugins plugin.json manifest. (Mafuuu)

Reword it to name Agent Plugins.

🤖

🤖 This review was automatically generated with Coder Agents.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread agent/proto/agent.proto Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread codersdk/agentsdk/agentsdk.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread agent/proto/agent.proto Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread codersdk/workspacesdk/frontmatter.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread agent/proto/agent_drpc_old.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread codersdk/workspacesdk/frontmatter_test.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread codersdk/deployment.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread agent/proto/agent.proto Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread codersdk/workspacesdk/frontmatter.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch 2 times, most recently from def34d5 to 10dbcb0 Compare October 2, 2026 22:00
@jscottmiller

jscottmiller commented Oct 2, 2026

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

coder-agents-review[bot] reacted with rocket emoji
All reactions
  • 🚀 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

coder-agents-review[bot]
coder-agents-review Bot reviewed Oct 2, 2026
View reviewed changes

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

This push makes coderd enforce the experiment and validate plugin names in PushContextState, and adds migration 000612. New findings: 2 P3, 4 P4, 1 Nit.

All 15 round-1 fixes were verified against the code. The defenses on the plugins_supported name and on the experiment description were accepted by the reviewers that raised them. The unused 2.12/2.13 client interfaces remain open; see the reply on that thread.

The test-go-pg CI failure was not attributed to this diff: the job log could not be read, and the PR's targeted tests and DB=ci go test ./coderd/database/migrations/ pass locally.

Notes:

  • coderd/agentapi/context.go:83: with the experiment off, the stored aggregate_hash still covers plugin resources that coderd dropped. This only happens when an agent ignores plugins_supported, and the field comment documents it.
  • The commit body still says agents dial v2.10 and that no migration is needed. The squash merge uses the PR body, which is accurate.

🤖 This review was automatically generated with Coder Agents.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/api.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread agent/proto/agent.proto Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread agent/proto/agent.proto Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch from 10dbcb0 to 2be2785 Compare October 2, 2026 22:55
@jscottmiller

jscottmiller commented Oct 6, 2026

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

coder-agents-review[bot] reacted with rocket emoji
All reactions
  • 🚀 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

coder-agents-review[bot]
coder-agents-review Bot reviewed Oct 6, 2026
View reviewed changes

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

This push removes plugin_source, replaces the skip with a rejection when plugin_name names no OK plugin, normalizes skill path separators, rejects empty plugin server_name, and makes plugins_supported per connection. New findings: 2 P3, 7 P4, 3 Nit.

All 11 round-7 findings were verified fixed. Removing plugin_source closed the field-mismatch class of bugs. The uncapped-input problem from round 7 remains through other fields; the first P3 lists them.

Out of scope (needs a ticket or explicit acceptance by a human):

  • agent/agentcontext/resolve.go:636: skill name %q is not kebab-case quotes a front-matter name of up to 64 KiB into ContextResource.Error, so one malformed SKILL.md can exceed the 4096-byte error cap and coderd rejects the whole push.

Notes:

  • coderd/agentapi/context.go:440: converting \ to / in both strings accepts mixed-separator sources such as /a\b/skills/x for plugin root /a/b, which the previous two-form check rejected. Only a buggy agent sends this.

🤖 This review was automatically generated with Coder Agents.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread agent/proto/agent.proto Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread codersdk/agentsdk/agentsdk.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread agent/proto/agent.proto Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context_test.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context_test.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread agent/proto/agent.proto Resolved

Uh oh!

There was an error while loading. Please reload this page.

@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch from f64e456 to ff177d1 Compare October 7, 2026 18:53
@jscottmiller

jscottmiller commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

/coder-agents-review

coder-agents-review[bot] reacted with rocket emoji
All reactions
  • 🚀 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

coder-agents-review[bot]
coder-agents-review Bot reviewed Oct 7, 2026
View reviewed changes

@coder-agents-review coder-agents-review Bot left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

This push bounds every quoted string in plugin validation errors, detects duplicate OK plugin names in a first pass, drops plugin data inside the indexed loop, and tightens the plugins_supported wording. New findings: 8 P4, 2 Nit.

All 11 round-8 findings were verified fixed; reviewers mutation-checked the new tests, and RejectsInvalidPluginFields now asserts each error stays under 4096 bytes with 200 KiB inputs. No P3 or higher remains. The new findings are wording, test gaps, and error clarity around collectOKPlugins and the PluginBody non-OK paragraph.

🤖 This review was automatically generated with Coder Agents.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread agent/proto/agent.proto Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread agent/proto/agent.proto Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context_test.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context_test.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/database/migrations/000618_context_resources_plugin_comments.up.sql Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch 2 times, most recently from d67febf to ed9af30 Compare October 12, 2026 23:00
@jscottmiller
jscottmiller marked this pull request as ready for review October 13, 2026 03:01
@jscottmiller
jscottmiller requested review from johnstcn, nickvigilante and spikecurtis as code owners October 13, 2026 03:01
@pr-queue-manager
pr-queue-manager Bot requested a review from ibetitsmike October 13, 2026 03:03
ibetitsmike
ibetitsmike requested changes Oct 13, 2026
View reviewed changes
Comment thread agent/proto/agent.proto Outdated
// enabled. When false, the agent must not discover plugins, and must
// not send plugin resources or set plugin_name on this connection,
// even if an earlier connection's manifest set it.
bool plugins_supported = 20;

@ibetitsmike ibetitsmike Oct 13, 2026

Copy link
Copy Markdown
Collaborator

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Honestly I'm not in love with introducing wire changes to say "we have an experiment". I'd drop this change and figure out how to live without it.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@jscottmiller jscottmiller Oct 14, 2026

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Agreed, I don't like it. I wanted to support at least one version of bi-directional compatibility and I'm not sure of a better approach. Let's say agent plugins land in version N. I want to support the case where an operator upgrades coderd to N, starts up workspaces, then rolls coderd back to N-1. If the agent continues to publish context that includes the PluginBody message, the old/current version of coder rejects the entire push (see

coder/coderd/agentapi/context.go

Line 396 in 31dd054

case nil:
), causing coderd to keep the old snapshot. We could update the agent to dial 2.13 then fall back, but that would be a new pattern and opens a can of worms.

If you can think of another approach I'm all ears; alternatively, we can accept the risk and ensure that the error is surfaced. Looking at this again, I'm realizing that restarting a workspace pulls a new agent binary; if that's the case, if someone does need to rollback they can do a mass restart. It also looks like our rollback strategy is just to restore a db snapshot, which sidesteps the stale data issue.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@ibetitsmike ibetitsmike Oct 14, 2026

Copy link
Copy Markdown
Collaborator

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

I think we should be able to surface the error correctly even without that field.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@jscottmiller jscottmiller Oct 16, 2026

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Updated this pr to remove the field, and updated the second PR to add a generic error to the push when the plugin payload is unsupported or otherwise breaks its contract with the coderd server.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/database/migrations/000618_context_resources_plugin_comments.up.sql Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread coderd/agentapi/context.go Resolved

Uh oh!

There was an error while loading. Please reload this page.

@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch 4 times, most recently from 426be75 to c4bda0b Compare October 15, 2026 02:20
@jscottmiller
jscottmiller requested a review from ibetitsmike October 16, 2026 00:41
@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch from c4bda0b to 831ef99 Compare October 16, 2026 01:01
@jscottmiller
jscottmiller requested a review from mafredri as a code owner October 16, 2026 01:01
ibetitsmike
ibetitsmike approved these changes Oct 16, 2026
View reviewed changes
spikecurtis
spikecurtis reviewed Oct 20, 2026
View reviewed changes
Comment thread agent/proto/agent.proto Outdated
string name = 2;
string description = 3;
// plugin_name is the owning Agent Plugin, or empty for a workspace skill.
string plugin_name = 4;

@spikecurtis spikecurtis Oct 20, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Why do this with a (soft) reference to the plugin, instead of, for example, embedding the Skills and MCP servers directly into the PluginBody message?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@jscottmiller jscottmiller Oct 20, 2026

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Good question - I have a mild preference to keep wire protocols like this flat though in this case it does lead to some additional stitching logic. I'll kick off a quick exploration on the nested version.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@spikecurtis spikecurtis Oct 20, 2026

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

The thing I dislike about references like this is that they can be wrong. I.e. the plug_name doesn't match any plugin.

With the embedded structure errors like that are simply unrepresentable, which eliminates a whole class of problems, making the server code tighter with fewer error cases to check.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch from 831ef99 to 8b7f074 Compare October 21, 2026 02:16
@jscottmiller jscottmiller changed the title feat: add agent-plugins experiment and Agent API v2.13 plugin messages feat: add agent-plugins experiment and Agent API v2.16 plugin messages Oct 21, 2026
spikecurtis
spikecurtis approved these changes Oct 21, 2026
View reviewed changes

@spikecurtis spikecurtis left a comment

Copy link
Copy Markdown
Contributor

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

Proto looks good!

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch from 8b7f074 to 068cb50 Compare October 21, 2026 16:22
@jscottmiller
feat: add agent-plugins experiment and Agent API v2.16 plugin messages
4b0cfc9
Adds the agent-plugins experiment and bumps the Agent API to v2.16 with
message-only changes for Agent Plugins (agent-plugins.org):

- ContextResource gains a PluginBody variant carrying validated plugin
  manifest fields and the plugin's skills and MCP servers as nested
  ContextResources.
- Manifest gains agent_plugins_enabled, which coderd sets when the
  agent-plugins experiment is enabled.

Agents dial v2.16, so they need a coderd that supports it.

coderd stores the plugin variant under the existing plugin body kind,
without its nested resources, and each nested skill and MCP server as
its own row. Migration 000632 adds a plugin_name column to
workspace_agent_context_resources and chat_context_resources. It holds
the plugin's name on each nested row and on an OK plugin's row, and the
hydrate, MCP sync, and re-pin queries copy it. With the experiment off,
PushContextState drops plugin resources and the resources nested in
them. It rejects pushes with invalid plugin names, OK plugin resources
without a name, two OK plugin resources with the same name, a non-OK
plugin that nests resources, nested entries with the wrong body kind,
plugin skill sources outside "<plugin source>/skills/", and plugin MCP
servers with an empty server_name or a source other than
"<plugin name>/<server_name>". Nested resources count toward the
1000-resource cap.

workspacesdk.ValidatePluginName implements the spec's plugin name
grammar (1 to 64 characters of a-z, 0-9, '.', '-', alphanumeric first
and last, no repeated separators) so the agent and coderd validate
names the same way.
@jscottmiller
jscottmiller force-pushed the scott/agent-plugins/1-api branch from 068cb50 to 4b0cfc9 Compare October 22, 2026 16:54
@github-actions github-actions Bot added the stale This issue is like stale bread. label Oct 30, 2026
@github-actions github-actions Bot closed this Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@spikecurtis spikecurtis spikecurtis approved these changes
@ibetitsmike ibetitsmike ibetitsmike approved these changes
@nickvigilante nickvigilante Awaiting requested review from nickvigilante
@johnstcn johnstcn Awaiting requested review from johnstcn
@mafredri mafredri Awaiting requested review from mafredri mafredri is a code owner
+1 more reviewer
@coder-agents-review coder-agents-review[bot] coder-agents-review[bot] left review comments
Reviewers whose approvals may not affect merge requirements

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@jscottmiller jscottmiller

Labels

stale This issue is like stale bread.

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

3 participants

@jscottmiller @spikecurtis @ibetitsmike
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.