persona-frontmatter.md 2.2 KB

Read this when touching persona definition parsing or frontmatter editing.

Persona file frontmatter

Purpose

Persona definitions are Markdown files in ~/.pi/agent/agents/ with an optional --- frontmatter block. The extension parses them with a hand-written YAML subset parser (no YAML dependency) and edits fields in place so user formatting/comments survive.

Data model

AgentDef (parsed): name, description, model (provider/id), thinking (ThinkingLevel), tools: string[], excludeTools: string[], prompt (path to external Markdown file, max 64 KB), body text.

Constant Value / location Meaning
AGENTS_SUBDIR agents subdir under ~/.pi/agent/
STATE_FILENAME agent-state.json persisted active persona name
MAX_PROMPT_FILE_BYTES 64 * 1024 hard cap for external prompt files
UNSUPPORTED_YAML_SCALAR_PREFIX /^[!&*[{\|>-]/ scalar prefixes that make the file "unsupported" (read-only in menus)
DEFAULT_EFFORT medium thinking level when unspecified

Business rules

  • Only a YAML subset is supported: flat key: value scalars and block lists (- item with 2-space indent, see DESCRIPTION_BLOCK_INDENT / isBlockValueLine). Anything containing an unsupported scalar prefix (!, &, *, [, {, |, >, - inline) marks the file as unsupported → shown but not editable.
  • Files may start with a UTF-8 BOM (UTF8_BOM constant) — must be stripped before parsing.
  • Frontmatter is optional; a file with body only is a valid persona (prompt only).
  • Field edits (updateFrontmatterFields) rewrite ONLY the target key's extent (findKeyExtent), leaving all other lines byte-identical — comments and blank lines inside frontmatter must survive.
  • Model IDs use exactly one / separator (MODEL_ID_SEPARATOR); thinking values validated against THINKING_LEVELS.
  • Tool entries may be glob-ish patterns (ssh-manager_*); they are expanded against tools registered in the running session (expandToolPatterns), not matched against a static list.
  • State file (agent-state.json) stores only the active persona name; if the named file no longer exists, the state is treated as absent (no error).

Cross-links

  • Module map: @specs/module-index.md