Personas, skills, and memory

This page documents Osprey source commit 01dabf2fedd1826362162ead9757232e89d9bfa5.

Select a persona

A persona defines its system prompt, tools, output contract, and subagent eligibility. Osprey resolves a named persona from the first matching layer.

Precedence Location
1 The project .osprey/personas/NAME.md file
2 The $OSPREY_HOME/personas/NAME.md file
3 A persona bundled into the Osprey binary

The default $OSPREY_HOME value is ~/.osprey. A project persona shadows a user or bundled persona with the same name.

Osprey bundles four personas.

Persona Purpose Spawnable Important limit
default General tasks Yes Uses the declared base tool set.
coding Repository changes and verification Yes Enables development tooling.
architect Read-only structured planning No Requires the submit_plan terminal tool and plan schema.
verifier Read-only success-criteria checks No Requires the submit_verification terminal tool and verification schema.

The default and coding personas declare this tool set:

read_file, write_file, edit_file, bash, process, find_files, grep,
list_directory, tree, todo_write, switch_persona, web_fetch

The architect and verifier prompts prohibit writes. Their frontmatter does not declare a tool allowlist.

Use --persona to select a persona for osprey agent. Without that option, [agent].default_persona selects the launch persona. Osprey uses the bundled default persona when neither setting exists.

osprey agent \
--persona coding \
"Inspect the current repository changes."

In the terminal user interface (TUI), enter /agents to open the persona picker. Enter /agents coding to select a listed persona by name. The picker lists project personas, user personas, default, and coding. The TUI switch path rebuilds the system prompt but does not replace a terminal tool or schema. Select a TUI terminal contract through [agent].default_persona before launch.

The switch_persona model tool changes the prompt on the next model turn. The selected persona remains active until another successful switch. The tool accepts resolved personas without a terminal contract during an interactive or headless session. Valid targets include default, coding, and eligible project or user personas.

The tool rejects personas that declare a terminal tool or output schema. Launch architect and verifier through osprey agent --persona instead. A failed switch leaves the current persona active.

Define a persona

Create one Markdown file for each custom persona. The file name must match the frontmatter name value.

---
name: reviewer
description: Reviews changes without editing files
spawnable: true
tools: [read_file, grep, find_files, list_directory, tree]
---
Review the requested changes. Report concrete findings with file locations.

Persona frontmatter supports these fields.

Field Requirement or default
name Required and equal to the file stem.
description Optional picker text.
terminal_tool Optional terminal tool for a launch-time output contract.
schema_path Optional JavaScript Object Notation (JSON) Schema path. Relative paths start at the persona directory.
spawnable Defaults to false. Only spawnable personas can run as child agents.
tools Optional list of exact tool names. Entries cannot be empty. Headless leads and child agents use the list as an allowlist.
toolset Optional named set from toolsets.toml for the headless lead.
dev_tooling Defaults to false. A true value adds detected project markers and available-tool details to the environment prompt.

For the headless lead, persona tools and the selected toolset compose by intersection. The osprey agent --toolset option overrides the persona's named toolset. The installed TUI does not filter its lead-agent tools through either persona field. Child agents apply persona tools but ignore the persona toolset field. A spawnable persona must declare a tools list. Every listed tool must exist in the child dispatcher's tool inventory.

The parser rejects missing frontmatter, missing names, and name mismatches. The parser also rejects unreadable or invalid JavaScript Object Notation (JSON) schemas. A missing bundled plan or verification schema uses the binary copy with the same file name. Other missing schema files cause persona resolution to fail.

Discover skills

A skill is a SKILL.md file with reusable model instructions. Osprey scans filesystem skill roots in this order:

  1. Project .agents/skills directories, from the working directory to the workspace boundary
  2. Each directory from the repeatable --skill-dir option
  3. The user skill directory used by runtime discovery

The first valid filesystem skill with a given name wins. Osprey prepends bundled skills before building the final registry. Therefore, a filesystem skill cannot shadow about-osprey or bug-report. An unreadable directory or invalid skill produces a warning without stopping other discovery.

Each skill needs frontmatter with name and description fields. Descriptions cannot exceed 1,024 characters.

A plain skill name uses lowercase letters, digits, and single hyphens. The name length is 1 through 64 characters. The name must match its parent directory.

A namespaced skill uses exactly one colon between two valid name parts. The second part must match the parent directory.

---
name: review-rust
description: Review Rust changes for correctness and maintainability.
---
Read the changed Rust files. Report findings with exact locations.

Osprey lists discovered skill metadata in the system prompt. The model loads a selected body through load_skill by registry name. The tool does not accept a caller-supplied path.

Use repeatable --skill options to preload skill bodies at session start. Each requested skill must already exist in the discovery registry.

osprey agent \
--skill review-rust \
"Review the current Rust changes."

Use --skill-dir to add an explicit skill root. The OSPREY_SKILL_DIR environment variable supplies the same option.

SKILL_ROOT="$PWD/team-skills"
osprey agent \
--skill-dir "$SKILL_ROOT" \
--skill review-rust \
"Review the current Rust changes."

User skill path discrepancy

The command help and runtime source disagree about the user skill root at this commit. The command help names ~/.agents/skills. Runtime discovery appends .agents/skills to $OSPREY_HOME. With the default home, that runtime expression resolves under ~/.osprey.

Use --skill-dir or OSPREY_SKILL_DIR when a user-wide location must be unambiguous. Do not depend on either implied default until the two source surfaces agree.

Skill commands and failures

Enter /skills to list discovered skills in the TUI. Enter /skill review-rust to inspect one skill's name, scope, description, and path. Project and user skills also become slash commands such as /review-rust. A built-in command wins when a slash name collides. A workflow wins when a workflow and skill share a non-built-in name.

Enter /reload to schedule extension and skill discovery for the next turn. The command reports an error when the session lacks a reload coordinator.

An unknown load_skill name returns the available names as a non-retryable error. An unreadable SKILL.md file also returns a non-retryable error. Invalid skills remain outside the registry.

Osprey bundles about-osprey and bug-report skills in the binary. The /bug-report command gathers required details. It requests confirmation before filing. After confirmation, the skill tries to create a public GitHub issue. If filing fails, the skill returns a prefilled GitHub issue link instead.

Configure persistent memory

The default memory provider is builtin. Use the global $OSPREY_HOME/config.toml file to configure memory.

[memory]
provider = "builtin"
memory_char_limit = 2200
user_char_limit = 1375

The default memory target stores project and context notes. The user target stores facts about the user. The default character limits are 2,200 and 1,375 respectively.

The memory model tool supports five actions.

Action Inputs Result
add content, optional target Adds one new entry or reports an existing duplicate.
replace old_text, content, optional target Replaces the single entry containing the unique substring.
remove old_text, optional target Removes the single entry containing the unique substring.
recall query Returns matching entries.
batch operations, optional target Applies ordered mutations to one target.

Store durable facts only. Do not store credentials or other secrets. Osprey rejects empty content and known instruction-injection patterns. Snapshot and recall output replace detected unsafe entries with a blocked marker.

Built-in memory files

The built-in provider uses these files:

  • $OSPREY_HOME/memory/MEMORY.md
  • $OSPREY_HOME/memory/USER.md
  • $OSPREY_HOME/memory/.lock

Missing memory files represent empty stores. Writes take an exclusive lock. They replace the target file atomically. Exact duplicate additions succeed without another write. An addition that exceeds the target limit fails without changing the file.

Replace and remove require a nonempty unique substring. No match or multiple matches cause failure without a write. A batch either commits all effective operations or commits none.

Recall splits the query on whitespace. Every query term must occur case-insensitively in a matching entry. Results contain newer entries before older entries within each target.

Osprey injects one frozen memory snapshot into the session system prompt. Writes during a session affect later sessions, not the existing snapshot. Explicit recall reads the latest provider state during the current session. The injected block reports character use for each nonempty target.

Manual edits can break the delimiter-only storage format. Before a replace, remove, or related batch, Osprey checks file integrity. On drift, Osprey writes a timestamped .md.bak file and refuses the mutation. Restore entries separated only by the memory delimiter before retrying.

After three memory write failures, the tool response tells the model to stop retrying. Recall failures do not increase this write-failure count.

Hindsight memory

The hindsight provider stores and recalls memories through an external Hypertext Transfer Protocol (HTTP) service.

[memory]
provider = "hindsight"
[memory.hindsight]
mode = "cloud"
bank_id = "osprey"
recall_budget = "mid"
timeout_secs = 120

Cloud mode uses https://api.hindsight.vectorize.io by default. Cloud mode requires a nonempty HINDSIGHT_API_KEY environment variable. Local external mode uses http://localhost:8888 by default. Set mode = "local_external" when another process hosts that service. Set api_url to replace the endpoint selected by mode.

The default bank is osprey. The default recall budget is mid. Valid budgets are low, mid, and high. The default request timeout is 120 seconds. Each recall requests at most 4,096 tokens.

The first operation probes the service version endpoint. Recall sends the query to the configured bank. The provider supports add and add-only batch operations. Those operations write memories to the configured bank. The provider uses the same bank for both memory targets.

Hindsight consolidates memories on the server. Replace and remove are unsupported. Store a corrected fact when an existing Hindsight memory becomes outdated.

Transport failures, timeouts, error statuses, and invalid responses produce memory errors. An invalid mode or recall budget prevents provider construction.

Set provider = "none" to disable the memory tool and memory prompt block. An unknown provider name prevents session startup.

Back to Osprey