Custom prompts

Overview

Custom prompts let you define reusable system messages that are prepended to every chat turn. Prompts can be configured at two scopes:

Usage

Managing prompts (Settings UI)

Prompts can be managed from two locations in Settings:

  1. Settings → App defaults → Custom prompts (#/settings/prompts): Manage global custom prompts that apply across all projects.

  2. Settings → This project → Custom prompts (#/settings/prompts?projectDir=...): Manage project-specific prompts and view inherited app-wide prompts.

    The Prompt picker lists every saved prompt (with a preset tag for ones that carry a tool/agent-file/skills preset; scope badges only appear on the project screen, where the two scopes are mixed, and are omitted on the single-scope App-defaults screen) plus a + New prompt entry for a blank form. Below the saved prompts, a Start from a default section lists the three built-in prompt-size profiles (Very small, Average, Extensive, each tagged default); tapping one opens a fresh unsaved prompt pre-filled with that profile's title and systemMessage, ready to edit and Create. This means the picker is never empty even before you have saved anything. It uses an in-app, theme-matched list instead of the platform select overlay, keeping the prompt content visible and avoiding oversized native menus on mobile. On first open the picker defaults to the first saved prompt so the editor is already populated; tapping New starts a blank form instead. Pick a prompt to load its title, content, and preset into the editor.

Older settings/prompts/:id URLs still resolve to the same screen with the picker pre-selected to that prompt, so saved links keep working.

Defining a chat preset

When creating or editing a prompt, toggle Chat preset on to attach a preset. The preset uses the same controls as the rest of the settings:

Using a prompt in a chat

  1. Open Settings → Agents.

  2. Choose a custom prompt on an agent and save its configuration.

  3. Select that agent as the project default or from the chat Agent card.

  4. The prompt is resolved from the selected agent and injected on every stream turn.

    The REST API can still set chat.promptId directly for a chat-specific override. Its precedence is higher than the selected agent's prompt.

    The prompt is not visible in the transcript — it is prepended server-side when building the upstream message array.

Schema

Each prompt is stored as an object:

{
  "id": "a1b2c3d4",
  "title": "Code reviewer",
  "icon": "code",
  "showOnProjectCard": true,
  "content": "You are an expert code reviewer. Be thorough and constructive.",
  "role": "system",
  "preset": {
    "tools": ["shell", "file", "mcp__chrome_debug__navigate"],
    "agentFiles": true,
    "skills": true
  },
  "createdAt": "2026-07-15T12:00:00.000Z",
  "updatedAt": "2026-07-15T12:00:00.000Z"
}

The icon field is restricted to built-in keys (sparkles, code, search, pencil, bug, or book); unknown values safely fall back to sparkles. showOnProjectCard defaults to false for existing prompts.

The role field is preserved on disk for forward-compat and hand-edits, but the editor and the validator only accept system. A non-system role in the file is silently coerced to system on read.

preset is optional. It is normalized to { tools?, agentFiles?, skills? }:

Chat integration (presets)

When the server processes POST /api/chats/:id/messages/stream, if the chat record has a promptId referencing an existing prompt, the server prepends { role: 'system', content: prompt.content } to the upstream message array before calling ai.streamChat. The prompt is not stored in the chat transcript — it is ephemeral and only sent to the model.

If the referenced prompt carries a preset, the chat's effective per-chat config for that turn also picks it up (via prompts.effectivePresetConfig):