Skip to content

feat: add ability to remove custom modes from Agent Behaviour settings - #7100

Merged
markijbema merged 10 commits into
mainfrom
mark/remove-available-modes
Mar 16, 2026
Merged

feat: add ability to remove custom modes from Agent Behaviour settings#7100
markijbema merged 10 commits into
mainfrom
mark/remove-available-modes

Conversation

@markijbema

@markijbema markijbema commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Adds a remove button (X icon) to each non-native custom mode in the Agent Behaviour > Agents settings tab
  • Shows a confirmation dialog before removing to prevent accidental removal
  • On confirm, disables the mode via config ({ agent: { [name]: { disable: true } } }) and refreshes the agent list
  • Webview optimistically removes the mode from the list; on backend failure, the list reverts to the authoritative state
CleanShot 2026-03-16 at 16 40 29

Mark IJbema added 4 commits March 16, 2026 15:49
Replace the config disable:true approach with a proper Agent.remove()
function that scans config directories for the agent's markdown file
and deletes it, then refreshes state via Instance.dispose().

- Add Agent.remove() in agent.ts with RemoveError
- Add POST /kilocode/agent/remove route
- Mount KilocodeRoutes in server.ts
- Update KiloProvider to call the new backend route
- Regenerate SDK
@markijbema
markijbema force-pushed the mark/remove-available-modes branch 2 times, most recently from b20553e to b90a223 Compare March 16, 2026 14:58
…igrator

Agent.remove() now also scans the .kilocodemodes YAML files that
ModesMigrator reads (VSCode global storage, ~/.kilocode/cli/global/,
~/.kilocodemodes, project .kilocodemodes) and removes the matching
entry by slug, so migrated modes don't reappear after deletion.
@markijbema
markijbema force-pushed the mark/remove-available-modes branch from aff7820 to b8e196d Compare March 16, 2026 15:01
Add a removing guard signal that prevents confirmRemoveMode from
firing during the 200ms window after clicking Remove. This avoids
a race condition where the dialog close animation + reactive list
re-render causes the next list item's click handler to fire.
@markijbema
markijbema force-pushed the mark/remove-available-modes branch from 61ca043 to a80d495 Compare March 16, 2026 15:06
Replace the removing guard signal with a simpler approach: delay
the optimistic list removal by 150ms so it happens after the
dialog's 100ms close animation completes. This prevents both the
double-dialog issue and the stuck-state issue.
@markijbema
markijbema force-pushed the mark/remove-available-modes branch from 489607e to a406741 Compare March 16, 2026 15:25
@markijbema
markijbema marked this pull request as ready for review March 16, 2026 15:45
))
}

const removableModes = createMemo(() => session.agents().filter((a) => !a.native))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: Delete button is shown for modes this API cannot remove

This filter treats every non-native agent as removable, but Agent.remove() only deletes markdown-backed agents or legacy .kilocodemodes entries. Modes declared directly in kilo.json/opencode.json are also native: false, so the UI will offer a remove action that always comes back with no agent file found on disk.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I'm willing to accept this for now, we need to iterate on this screen anyways. it's good enough for supporting the marketplace

const [skills, setSkills] = createSignal<SkillInfo[]>([])

const removeMode = (name: string) => {
setAgents((prev) => prev.filter((a) => a.name !== name))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: Removed mode can stay selected in session state

removeMode() only updates the agents list. If the user deletes the mode currently stored in agentSelections or pendingAgentSelection, selectedAgentName() keeps returning that stale value, and the next sendMessage() still forwards it to the backend. Agent.get(input.agent) then resolves undefined in session/prompt.ts, which turns this into a runtime failure instead of falling back to the new default mode.


// 1. Delete .md files from config directories
const dirs = await Config.directories()
const patterns = ["{agent,agents}/**/" + name + ".md", "{mode,modes}/" + name + ".md"]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: File lookup assumes the agent name matches the markdown filename

loadAgent() and loadMode() let frontmatter override name, and the webview posts back agent.name here. If a custom agent is defined in foo.md with name: "bar", this pattern searches for bar.md and never finds the backing file, so deleting renamed agents fails even though they appear removable in the UI.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

please don't do this 😅 . again, acceptable for now

@kilo-code-bot

kilo-code-bot Bot commented Mar 16, 2026

Copy link
Copy Markdown
Contributor

Code Review Summary

Status: 2 Issues Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 2
SUGGESTION 0
Issue Details (click to expand)

WARNING

File Line Issue
packages/kilo-vscode/src/KiloProvider.ts 1188 Successful mode removal does not refresh or clear stale config references, so deleted defaults can keep appearing and break fallback agent resolution.
packages/opencode/src/agent/agent.ts 473 The removal path interpolates name into a glob without escaping metacharacters, which can delete unrelated agent markdown files.
Other Observations (not in diff)

No additional issues outside the diff.

Files Reviewed (26 files)
  • packages/kilo-vscode/src/KiloProvider.ts - 1 issue
  • packages/kilo-vscode/tests/visual-regression.spec.ts-snapshots/settings/agent-behaviour-agents-chromium-linux.png - 0 issues
  • packages/kilo-vscode/webview-ui/src/components/settings/AgentBehaviourTab.tsx - 0 issues
  • packages/kilo-vscode/webview-ui/src/context/session.tsx - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/ar.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/br.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/bs.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/da.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/de.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/en.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/es.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/fr.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/ja.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/ko.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/no.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/pl.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/ru.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/th.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/zh.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/i18n/zht.ts - 0 issues
  • packages/kilo-vscode/webview-ui/src/types/messages.ts - 0 issues
  • packages/opencode/src/agent/agent.ts - 1 issue
  • packages/opencode/src/server/routes/kilocode.ts - 0 issues
  • packages/sdk/js/src/v2/gen/sdk.gen.ts - 0 issues
  • packages/sdk/js/src/v2/gen/types.gen.ts - 0 issues
  • packages/sdk/openapi.json - 0 issues

Fix these issues in Kilo Cloud


Reviewed by gpt-5.4-20260305 · 1,514,317 tokens

When removeMode() is called, also clear any agentSelections entries
and pendingAgentSelection that reference the removed mode. Without
this, selectedAgentName() keeps returning the stale value and
sendMessage() forwards it to the backend where Agent.get() resolves
undefined.
}
// Invalidate cache so next requestAgents fetches fresh data
this.cachedAgentsMessage = null
await this.fetchAndSendAgents()

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: Removed mode leaves stale config references behind

This only refreshes agentsLoaded. If the deleted mode is still referenced by config.default_agent or config.agent, the webview keeps showing it from stale config state and the backend can start throwing default agent "<name>" not found when the next prompt falls back to the default agent. Refresh or clear the config after a successful removal as well.

const patterns = ["{agent,agents}/**/" + name + ".md", "{mode,modes}/" + name + ".md"]
for (const dir of dirs) {
for (const pattern of patterns) {
const matches = await Glob.scan(pattern, { cwd: dir, absolute: true, dot: true })

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

WARNING: Agent name is used as an unescaped glob

name comes straight from the request body and is interpolated into the glob pattern here. Because custom agent names are not validated to exclude glob metacharacters, a mode named with *, ?, [], or {} can match and delete unrelated .md agent files. Escape the slug before calling Glob.scan, or build the expected path directly.

@markijbema
markijbema merged commit 457ff17 into main Mar 16, 2026
13 checks passed
@markijbema
markijbema deleted the mark/remove-available-modes branch March 16, 2026 16:00
slamj1 pushed a commit to slamj1/kilocode that referenced this pull request May 16, 2026
jliounis pushed a commit to jliounis/kilocode that referenced this pull request May 18, 2026
jliounis pushed a commit to jliounis/kilocode that referenced this pull request May 18, 2026
…modes

feat: add ability to remove custom modes from Agent Behaviour settings
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
t7tran pushed a commit to t7tran/kilocode that referenced this pull request Aug 14, 2026
…modes

feat: add ability to remove custom modes from Agent Behaviour settings
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