GeezerVison is showing github.com — feat: send skill invocations as structured message parts by jaaydenh · Pull Request #30861 · coder/coder
Conversation
jaaydenh
commented
Oct 15, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
Adds a structured skill-invocation chat part so a user message can carry an explicit skill. chatd loads that exact skill when the message is sent and puts its body into the user's prompt, so the skill always applies instead of relying on the model to notice it in <available-skills>. The composer chip that sends these parts comes in the next PR.
- codersdk: a
skill-invocation input part and message part with skill_source (personal, org, project, workspace) and skill_name. The resolved body is stored on the part as internal skill_body; it's hidden from TypeScript and stripped from every API response.
- coderd rejects an unknown source or an invalid name with 400.
- chatd resolves each invocation on create, send and edit with the chat owner's permissions, through the same loaders as
read_skill: stored skills by source and name (project skills through the chat's project, with the root chat fallback for subagents) and workspace skills from the pinned context snapshot. The body is saved at send time so past turns show what the model received. A missing, disabled or unreadable skill rejects the send with 400 "Skill project/triage is not available."
- The prompt renders a line saying the user invoked the skill, followed by
<invoked-skill name="project/triage"> with the sanitized body. Titles and hook prompt text show the invocation as /project/triage.
- The site only gets no-op cases so the regenerated types compile.
coderd/x/chatd/ARCHITECTURE.md gets a TODO for the author.
Stack (merge top to bottom):
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Add sqlc queries for skills owned by a chat project and authorize them
through the parent project in dbauthz: reading needs chat_project:read
and writing needs chat_project:update. Skill.RBACObject keeps denying
project rows so any unwrapped path fails closed.
Add the chat_project_skill audit resource type and
AuditableChatProjectSkill so the upcoming project skill API can record
audit entries.
Add experimental routes to list, create, read, update and delete skills
on a chat project. Reading needs read on the project and writes need
update; callers who lack the permission get a 404 like the project
instructions routes. The handlers reuse the shared skill create and
update path, map the per-project cap and name index to 409, and audit
every write as a chat_project_skill.
Add matching ExperimentalClient methods.
Chats in a project now get the project's enabled skills as a new
"project" skill source, read as the chat owner each turn. Subagents use
the root chat's project. read_skill loads project skill bodies, and
MergeSkills takes sources in merge order so new sources do not change
its signature.
The "/" menu offers the skills of the chat's project, next to personal,
organization and workspace skills, and /clear and /compact defer to a
project skill with the same name. Documents project skills.
…g in the slash menu
Organization and project skills load through one hook, and the menu
renders its skill groups from one ordered list. Adds project loading and
error stories.
…lify skill group offsets
…nd resolve emptiness in the hook
Cover the project-only skill tool check in the integration test, the
project skill body loader's not-found mapping, and the chat-projects
experiment gate in the composer.
… request instead of menu markup
…ed skill helpers
Split the form body of SkillEditor into SkillEditorForm, settle saves
through a mutate callback so the editor stays locked until the request
finishes, move the read-only enabled indicator into SkillEnabledSwitch,
and share the empty and loaded form value helpers in utils/skills.ts.
Add API methods and query factories to read, create, update, and delete
chat project skills, a projectSkillsScope for the shared skill helpers,
and ProjectSkillsDialog, which lists a project's skills and edits them
with SkillEditorForm.
Add a Skills row to the project Details panel that opens
ProjectSkillsDialog, with stories for the dialog and the panel, and
document where project skills are managed.
Add a skill-invocation chat input and message part. chatd loads the
invoked skill body with the chat owner's permissions when a message is
created, sent, or edited, stores it on the part, and renders it into
the user's prompt inside <invoked-skill>. Unavailable skills reject the
request with a 400. The stored body is internal and never returned by
the API.
… focusable and cover submit settlement
…t-skills/project-skills-dialog
…ts through refetches and handle deleted skills
…oject-skills/project-skills-details
… and toggle tests to the Details row PR
…downloads, toggles, refetches and deleted skills
…roject-skills/invocation-api
This was referenced Oct 15, 2026
…dialog
# Conflicts:
# site/src/api/queries/chatProjectSkills.ts
…lls-details
# Conflicts:
# site/src/api/queries/chatProjectSkills.ts
…-api
# Conflicts:
# coderd/exp_chats.go
Turns check project access once with resolveUsableChatProjectID and then
load instructions and skills, so resolveProjectInstructions had no
production callers. Its tests now cover resolveUsableChatProjectID and
loadProjectInstructions directly.
…coder into chat-project-skills/chatd
…retry prompt for unusable projects
A 403 or 404 from the project skills request means the caller lost access
to the project, which the composer already treats as no project skills.
The slash menu still showed "Could not load project skills" with a retry
hint that could never succeed, so a project the caller cannot use no longer
shows a loading or error status. A story covers the menu in that state.
jaaydenh
added a commit
that referenced
this pull request
Oct 21, 2026
Chats that belong to a chat project now get the project's skills, next
to personal, organization and workspace skills. They show up in the
model's skill list, load through `read_skill`, and appear in a "Project
skills" group in the `/` menu.
- `coderd/x/skills` adds the `project` source. `MergeSkills` now takes a
list of sources in merge order (personal, organization, project,
workspace). Bare names stay bare unless two sources share a name, in
which case they get `project/<name>` style aliases.
- chatd loads project skills only when the chat owner owns the project
or the project is shared with them. Role grants don't count. This is the
same `usableChatProject` check that project instructions and memory use,
and one check per turn covers both instructions and skills. Disabled
skills are skipped. A failed load logs a warning and the turn continues
without them. Subagents use their root chat's project; that lookup is
now a helper shared with project instructions.
- The site loads project skills for the composer on the project page and
in project chats, behind the `chat-projects` experiment. `/clear` and
`/compact` defer to a project skill with the same name, as they already
do for other sources. When the user can't use the project, the site
treats it as no project skills, like chatd, so those commands keep
working and the `/` menu shows no retry prompt for project skills. That
covers a 403 or 404 from the project skills request and a project
missing from the user's project list, which holds only owned and shared
projects, so an administrator role that can read the project doesn't
count. Other failures are retried and leave the list unknown. A cached
project list is also unknown while it refetches or after a failed
refetch, so a share revoked since it was cached keeps those commands
pending instead of deferring to stale project skills.
- Docs gain a "Project skills" section in the extending agents page.
`coderd/x/chatd/ARCHITECTURE.md` gains a paragraph on project skills.
Dogfood UAT on this branch passed: project skills appear in the project
page `/` menu and in project chats, `read_skill` loads them, disabled
and deleted skills report not found, chats outside the project don't see
them, and a subagent gets them through its root chat. The site reads
project skills from the chat's own `project_id`, so subagent chats show
them in the composer once sub-chats carry their root's project (#30683).
| Project page `/` menu | `read_skill` in a project chat |
| --- | --- |
| <img alt="Project skills group in the project page slash menu"
src="https://raw.githubusercontent.com/coder/coder/assets/pr-30838-project-skills/pr/project-page-slash-menu.png"
width="600" /> | <img alt="read_skill loading a project skill in a
project chat"
src="https://raw.githubusercontent.com/coder/coder/assets/pr-30838-project-skills/pr/project-chat-read-skill.png"
width="600" /> |
Stack (merge top to bottom):
- #30838 👈
- #30854
- #30855
- #30856
- #30861
- #30880
- #30881
- #30882
- #30884
- #31122
jaaydenh
added a commit
that referenced
this pull request
Oct 21, 2026
…ed skill helpers (#30854)
Pulls the skill form body out of `SkillEditor` into a `SkillEditorForm`
with no dialog wrapper, and moves the row helpers (download, delete
confirmation, form values from a skill) out of
`SkillsTable`/`SkillsTableView` so the project skills dialog in the next
PR can reuse them. `SkillEnabledSwitch` gains a `readOnly` prop.
The personal and organization skill pages behave the same, with two
small fixes that came along: Save is locked while a submit is in flight,
so a double click no longer sends two create requests, and the Body
placeholder renders its line breaks.
Stack (merge top to bottom):
- #30826
- #30827
- #30838
- #30840
- #30854 👈
- #30855
- #30856
- #30861
- #30880
- #30881
- #30882
- #30884
- #31122
jaaydenh
added a commit
that referenced
this pull request
Oct 21, 2026
Adds `ProjectSkillsDialog`, the dialog for managing a chat project's
skills, plus the API client methods and react-query factories for the
project skill routes from #30827. Nothing opens the dialog yet; the next
PR adds the entry point in the project page Details panel.
- List view: "Project skills" with each skill's name, description, an
enabled switch and last updated time, a row menu with Edit (View when
read-only), Download and Delete, and a "No skills added yet" empty
state.
- New and Edit replace the list inside the same dialog and reuse
`SkillEditorForm`, including paste-to-import and file upload. Name is
locked when editing, and Escape asks before discarding unsaved edits.
- Without update permission the dialog is read-only: no New, Delete or
Save, and fields are disabled.
- Create, update and delete invalidate the project skill list, so the
composer `/` menu picks up changes too. A 409 (duplicate name or the
100-skill cap) is shown in the form and refreshes the list.
Stack (merge top to bottom):
- #30826
- #30827
- #30838
- #30840
- #30854
- #30855 👈
- #30856
- #30861
- #30880
- #30881
- #30882
- #30884
- #31122
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
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.
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.
|