Personalities
June 30, 2026 · View on GitHub
Personalities are dynamic system prompt generators for .chat buffers. Each personality is a Lua module that assembles a markdown prompt from pre-built data — available tools, environment context, and project-specific files. Personalities are the most direct environment-shaping surface of the harness — they determine what the model knows about its identity, capabilities, and surroundings before it reads the conversation.
Usage
Include a personality in your system prompt using the include() expression with a URN:
@System:
{{ include('urn:flemma:personality:coding-assistant') }}
The personality generates a complete system prompt section with tool listings, behavioral guidelines, environment context, and any project-level instructions it discovers.
Built-in Personalities
coding-assistant
Generates a prompt for LLM-powered coding assistance. Includes:
- Core persona — identifies the assistant as a coding-focused agent in Neovim
- Available tools — lists the tools resolved for the buffer with short descriptions (enabled tools by default, plus any disabled tools explicitly listed in frontmatter)
- Guidelines — behavioral rules contributed by tool definitions
- Environment — working directory, current file, git branch, date/time
- Project context — auto-discovered files like
AGENTS.md,CLAUDE.md,.cursorrules
Project Context Discovery
The personality scans the directory containing the .chat file for these files (in order). For unnamed buffers with no file on disk, it falls back to the current working directory:
AGENTS.mdCLAUDE.md.claude/CLAUDE.md.cursorrules.github/copilot-instructions.md
Files with identical content (e.g., symlinks) are deduplicated — only the first match is included.
Note
Prompt caching: The date and time in the environment section are captured once per buffer session and reused for all subsequent requests. This keeps the system prompt identical across requests, enabling LLM provider prompt caching. Other environment fields (working directory, current file, git branch) are always fresh. The cached date/time is cleared automatically when the buffer is wiped. The tool list is also sorted alphabetically by name so its ordering stays stable across requests for the same reason.
Creating a Personality
Built-in personalities live under lua/flemma/personalities/styles/ (the styles/ sub-folder is the role — "this is what a personality module looks like"). Your own personalities can live anywhere on the Lua path; only the registration step cares about the module name. Each personality module implements a render() function:
---@class flemma.personalities.MyPersonality : flemma.personalities.Personality
local M = {}
---@param opts flemma.personalities.RenderOpts
---@return string
function M.render(opts)
local lines = {}
table.insert(lines, "You are a specialized assistant.")
table.insert(lines, "")
-- Use opts.tools, opts.environment, opts.project_context
-- to build your prompt however you like
return table.concat(lines, "\n")
end
return M
Personalities are autonomous — Flemma does not prescribe a template or section structure. The personality owns its format entirely.
RenderOpts
The opts table is pre-built before render() is called. The personality does no data gathering.
---@class flemma.personalities.RenderOpts
---@field tools flemma.personalities.ToolEntry[]
---@field environment flemma.personalities.Environment
---@field project_context flemma.personalities.ProjectContextFile[]
Tools
The tools resolved for the current buffer's prompt, sorted alphabetically. By default this is the set of enabled tools, but flemma.opt.tools in frontmatter may explicitly list disabled tools — those are also included here (disabled tools that aren't explicitly listed are excluded). Each entry has:
---@class flemma.personalities.ToolEntry
---@field name string
---@field parts table<string, string[]>
parts contains personality-specific data contributed by the tool definition, keyed by arbitrary part names. Tools without parts for this personality have an empty parts table.
Environment
---@class flemma.personalities.Environment
---@field cwd string
---@field current_file? string -- relative to cwd
---@field filetype? string
---@field git_branch? string
---@field date string
---@field time string
Project Context
---@class flemma.personalities.ProjectContextFile
---@field path string -- relative to the chat-file's directory (cwd for unnamed buffers)
---@field content string
Adding Parts to Tool Definitions
Tool definitions can contribute personality-specific parts via the personalities field:
{
name = "my-tool",
description = "Tool description for the API",
input_schema = { ... },
personalities = {
["coding-assistant"] = {
snippet = "Short description for the tools list",
guidelines = {
"Use my-tool when you need to do X",
"Always verify results before proceeding",
},
},
},
}
Part names (snippet, guidelines, etc.) are not prescribed by Flemma. They are whatever the personality module expects to find. Single string values are normalized to { value } when building opts.
Registering a Built-in Personality
Add the module path to BUILTIN_PERSONALITIES in lua/flemma/personalities/init.lua. The registration name (the table key) is the user-facing identifier — use a hyphenated string. The value is a dot-delimited Lua module path:
local BUILTIN_PERSONALITIES = {
["coding-assistant"] = "flemma.personalities.styles.coding_assistant",
["my-personality"] = "flemma.personalities.styles.my_personality",
}
The personality is loaded via flemma.loader and registered during setup(). The hyphen-vs-underscore split (hyphen in the name, underscore in the file path) follows Flemma's general convention — user-facing identifiers use hyphens, on-disk filenames use snake_case.