Role author path

Define and customize agent roles

Roles package a reusable agent policy: model, thinking level, tools, skills, extensions, prompt instructions, and context-file scope. Use a role file for stable defaults, then use per-call AgentOptions to override model, thinking, capabilities, and context files.

Overview

A workflow agent selects a role by name. The role body always comes from the named file. Per-call AgentOptions override the role-file defaults.

const plan = await agent("Plan the implementation", {
  role: "planner"
});

const fastReview = await agent("Review this change", {
  role: "reviewer",
  model: "cheap-model",
  contextFiles: ["cwd"],
  tools: ["!*", "read", "grep"]
});

Per-call model, thinking, tools, skills, extensions, and contextFiles override role-file defaults. Role extensionSettings replaces declared top-level namespaces while retaining omitted ones. Built-in subagent tools discover these same role files and apply the same validation to standalone agent runs.

Launch Pi with a role

pi-role, shipped by @piewf/cli, starts a regular Pi session with a role's model, tools, skills, extensions, and system prompt. No workflow, no subagent: the same role file, applied to the Pi you type into.

npm install -g @piewf/cli
pi-role                            # list the available roles
pi-role reviewer                   # interactive Pi as the reviewer role
pi-role scout -p "Where is the retry logic?"
pi-role developer --continue       # resume the last session
pi-role reviewer --approve         # trust the project: its roles apply
npx -p @piewf/cli pi-role oracle   # without installing

Every argument after the role name is forwarded to Pi unchanged. pi-role sees the bundled starter roles, global roles, and, in a trusted project, project roles; roles contributed by workflow extensions are only visible inside workflows. Requires the pi command on PATH. After pi install npm:@piewf/cli the binary lives in ~/.pi/agent/npm/node_modules/.bin/pi-role, which is not on PATH; prefer npm install -g.

What the role becomes

Role fieldPi arguments
model--model provider/model[:thinking]. A model alias that is not configured (for example the starter roles' developer-model, which the workflow extension resolves against the launching session) is reported on stderr and Pi starts with its default model.
tools--tools a,b,c. Selectors match Pi's builtin tools plus the tool names the role requests, so extension tools such as web_search pass through.
skills--no-skills --skill <path>... for each selected skill.
extensions--no-extensions --extension <path>... for each selected extension.
Role body--append-system-prompt, or --system-prompt when overrideSystemPrompt is true.
contextFilesAll scopes: nothing. []: --no-context-files. A subset of scopes is rejected because the launcher does not reconstruct partial project context.

Trust

Trust follows Pi's saved project decision. Without one, project roles, settings, skills, and extensions stay out until you pass --approve; --no-approve forces the opposite. The last flag before -- wins, as in Pi.

Standalone roles API

The pi-extensible-workflows/roles subpath exposes role discovery without creating a workflow or host. Use discoverRoles({ cwd, agentDir, projectTrusted, extensionRoleDirectories }) to load the active definitions, loadRole(name, options) to load one validated role, and resolveRole(name, options) to obtain its effective model, prompt mode, context scopes, selector layers, selected resources, and unmatched selectors. Optional resources, rootTools, knownModels, availableModels, and modelAliases provide the runtime boundaries needed for matching and model resolution; without them, selector layers are returned, while selected resources and tools remain unknown rather than being inferred.

Role files

Global roles live under <agentDir>/pi-extensible-workflows/roles/<name>.md, normally ~/.pi/agent/pi-extensible-workflows/roles/<name>.md. Set PI_CODING_AGENT_DIR to change the agent directory.

Trusted project roles live under <cwd>/.pi/pi-extensible-workflows/roles/<name>.md. A trusted extension can provide packaged defaults with roleDirectories, using an absolute path or a file: URL. Role precedence is starter roles < user extension roles < global roles < trusted project roles. Starter roles are low-precedence fallbacks, so a regular extension role silently overrides a starter role with the same name; duplicate names among regular extension roles are rejected. The bundled starter roles follow that rule; see Bundled starter for aliases, reviewLoop, and how to disable the factory.

---
description: Reviews code for correctness
model: anthropic/claude-fable-5:high
tools: ["!*", read, grep]
skills: ["!*", "review-*"]
extensions: ["!**/unsafe.mjs"]
---
Focus on correctness and regressions.

The body is prompt guidance. It is appended to the native Pi system prompt unless overrideSystemPrompt: true is set. Role files are trusted configuration and can affect model, tools, resource selectors, extension settings, and the system prompt.

Frontmatter fields

FieldPurpose
descriptionRole description shown in role discovery and Pi guidance.
modelConfigured alias or concrete provider/model:thinking.
tools, skills, extensionsOrdered Minimatch selectors. Positive patterns enable discovered candidates, !pattern disables them, later layers override earlier layers, and !* clears the current selection before narrower additions.
extensionSettingsJSON object of extension-owned namespace values. Declared top-level namespaces replace inherited values; omitted namespaces remain inherited.
overrideSystemPromptWhen true, use the role body instead of appending it to the native system prompt.
contextFilesChoose which Pi context-file scopes reach the role.

Relative extension selectors in role frontmatter resolve from the role file's directory; call-level selectors resolve from the agent launch cwd. See the settings reference for ~, file://, glob, and canonicalization rules.

Customize calls

role is a name string. Per-call model, tools, skills, extensions, and contextFiles override the role file. Concrete models are provider/model:thinking. overrideSystemPrompt stays on the role file.

await agent("Inspect the API", {
  role: "reviewer",
  contextFiles: ["cwd"],
  model: "cheap-model:low",
  tools: ["!*", "read", "grep"]
});

Use tools: ["*"] to re-enable all tools after a role restriction.

Context and resources

contextFiles controls Pi context discovery for that role. global selects the Pi agent-directory file, cwd selects the exact working-directory file, and project selects discovered project and ancestor files excluding those two. Omit the field for normal discovery or use [] to load none. Scopes can be combined.

---
contextFiles: [global, project]
skills: ["!*", "review-*"]
extensions: ["!*", "**/review-tools/**"]
tools: ["!*", read]
---

Selectors affect only agents using the role and compose after global and trusted-project selectors. Use piewf doctor --role <name> to inspect selector sources and effective skills, extensions, and tools without contacting a provider.

Inspect a role

npx piewf doctor --role reviewer
npx piewf doctor --role reviewer --prompt "Review the current change"
npx piewf doctor --role reviewer --json

The role inspection is read-only. The positional form piewf doctor reviewer is equivalent to --role reviewer. Both resolve the active role and report its effective resources and prepared prompt. The optional probe prompt is useful when prompt hooks depend on the agent request. Add --json to emit the structured report for machine consumers; either role form includes roleTarget and includes roleInspection when inspection succeeds.

Role discovery is fail-closed: invalid frontmatter or the rejected legacy selector in any packaged or global role file, or in any trusted-project role file, blocks the complete role set. See the doctor reference for diagnostics and exit behavior. At runtime, a missing named role fails with UNKNOWN_AGENT_TYPE and Unknown agent role: <name>.

See workflow tool usage, settings for model aliases and global selectors, and extension resources for packaged role directories.