pi-native-agents0.6.0
Focused Pi child sessions over Pi's native RPC API. Scout, reviewer, worker, and researcher.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
pi-native-agents
Focused child Pi sessions using Pi's public RPC API, not a third-party subagent engine.
Version 0.6.0. Node CLI Pi 1.3.x, Node >=22.19.
No bundled runtime dependencies, daemon, or dependency on pi-subagents.
This is a Pi extension package, not an upstream Pi core modification.
Four roles, all parent MCP
| Agent | Purpose | Native tools |
|---|---|---|
scout |
Code reconnaissance with file references | read, grep, find, ls |
reviewer |
Evidence-backed code review | read, grep, find, ls |
worker |
Scoped implementation and validation | read, grep, find, ls, edit, write, bash |
researcher |
Cited web/docs research | read, grep, find, ls |
Every role additionally inherits all MCP tools callable by the parent. This includes mutating tools and MCP resource helpers. Native read-only loadouts do not make inherited MCP access read-only.
Reviewer has no native shell: provide the diff in context or a readable patch file. Worker can run native validation when the assignment authorizes it. Researcher uses whatever suitable search/fetch capabilities the parent already has; no search service or login is bundled.
Install
# npm release:
pi install npm:pi-native-agents
# Tagged GitHub source:
pi install git:github.com/YellowFoxH4XOR/pi-native-agents@v0.6.0
To try a checkout without saving settings:
npm run check
pi -e ./index.js
For a persistent local checkout, use pi install /absolute/path/to/pi-native-agents.
Restart Pi or run /reload. Do not load local and npm copies simultaneously.
Pi supplies @earendil-works/pi-coding-agent and typebox as optional host peers.
There is no build step or separate runtime install.
Source and issues: YellowFoxH4XOR/pi-native-agents.
Usage
Ask naturally:
- "Use scout to map authentication."
- "Have reviewer inspect this supplied patch."
- "Have worker implement the approved change, then reviewer check it."
- "Use researcher to compare these APIs and cite primary sources."
The task tool takes one assignment or a batch:
{ agent: "scout", task: "Trace session persistence", context: "Focus on resume." }
{ tasks: [
{ agent: "scout", task: "Trace producer-side dispatch" },
{ agent: "reviewer", task: "Check consumers against this patch", context: "..." }
] }
Unknown fields are rejected. No arbitrary cwd override. Children get only their role prompt, assignment, optional context, and tool metadata; they do not inherit the parent transcript.
Runs, history, and cost
/agents is a flat run dashboard, not a role-first drilldown:
- 1 Active — running and queued jobs, with assignment, role, state, age and cost.
- 2 History — finished jobs with DONE, FAILED, STOPPED or PARTIAL outcomes.
- 3 Roles — model/thinking settings per definition; E, Enter or click edits a role.
Press
fto filter its runs. Opening settings never launches a model request.
Twenty workers appear as twenty separate rows. Click/Enter goes directly to that
job's detail. /agents worker filters the dashboard to workers; a clears the filter.
The selected row stays bound to its ID during updates. A finishing/disappearing
selection cannot silently redirect Stop to a different worker.
Details pin the assignment, run/session cost, model and state. Output contains
streaming/final text; Timeline contains retained tool events. Tab or o/t
switches them. Up/Down, PageUp/PageDown and the wheel scroll; manual scrolling pauses
follow, End/f resumes it. s or Stop run cancels only that run. Esc returns to the
table and then closes it; Ctrl+C closes the view. Closing never cancels work.
Mouse clicks require fullscreen mode; keyboard navigation also works in regular mode.
A model run returning normally is not proof all work succeeded. DONE/WARN flags completed runs that encountered tool errors; inspect their output/timeline. Restored history has results but not the old live trace; missing tool counts are shown as unavailable, not as a fabricated zero.
Configure a role once, reuse it on every call
/agents → 3 Roles → select scout/worker/reviewer/researcher → E.
Choose Model (or m) to search the configured native-child model catalog by
provider/name/ID. Choose Thinking (or t) to see levels supported by that model.
Press Save / s. Esc discards the draft. Selecting a model/level alone does not
save it. The Roles table immediately shows saved values and inherited parent values.
An explicit saved model and thinking level are fixed for that role on every new dispatch, including all 20 Worker instances. They survive reloads/restarts. The parent does not auto-pick a different model or effort per assignment and there is no fallback. Changing the parent's model does not change a role with explicit overrides.
Parent is an explicit inheritance option, represented by JSON null; leaving a role unset also uses its definition/parent defaults. Selecting Parent for a field allows that field to follow future parent choices. Pi can clamp inherited effort when the model does not support it. Explicit selections are validated in the picker.
Saves affect future task calls immediately; already-dispatched running/queued jobs
keep their snapshots. Parent startup model/thinking and global Pi settings are not
modified. Settings are stored in personal native-agents.json, or the effective
trusted-project override when one already owns that role (shown in the editor).
Atomic merge/locking preserves unrelated settings and refuses stale same-role edits
or symlinked files. Role-file/frontmatter overrides still obey the normal precedence.
The catalog uses configured parent availability, parent model scope and a native child catalog intersection. Unsupported extension-only providers are not offered. Configuration availability is not a guarantee of upstream entitlement/quota. Reading the catalog starts a short-lived metadata-only Pi RPC process, not an LLM turn or MCP server. It is cached while the dashboard remains open and cancelled on close. No credentials or provider URLs are copied into role settings.
For latency, the UI suggests low for scout, medium for worker/researcher, high for
reviewer (or a supported alternative). These are suggestions, not automatic changes.
l applies the suggestion to the draft; Save is still required. In particular,
inheriting parent max thinking can be slow. Model/server/MCP/process startup latency
remains; prompt changes alone do not guarantee speed.
Automatic delegation, without making you request each role
Default "delegation": "auto" gives the parent a role-selection policy at turn start.
It chooses useful scoped specialists itself, but keeps tiny known-file/sequential
work in the main session. It prefers one investigate+edit owner over a mandatory
scout→worker→reviewer chain, the smallest useful fan-out, and one integrated
validation pass rather than a full build/test pass per parallel worker.
This is model-facing guidance, not a hidden classifier, an always-spawn hook or an
extra model call. User no-agent/read-only constraints and all authorization boundaries
still apply. Automatic delegation chooses the role, never changes that role's
saved model/thinking. Set "delegation": "manual" to retain explicit-request behavior.
The child prompts stay focused and return compact results with evidence/gaps.
We inspected the installed OMP 18.12.5 bundled prompts and current upstream task guidance; see reference notes. The prompt text here is original and does not import OMP's background execution, approval bypass or auto-thinking classifier. No new skills/runtime packages were installed.
Session subagent cost in the footer
The existing footer receives standard Pi status text, for example:
Subagents $0.1308 est · 3 running · 2 queued
The package calls ctx.ui.setStatus(), not setFooter(), so it does not replace
your footer. A third-party custom footer must render getExtensionStatuses() to
show the status; the current enhanced status-line extension does so.
- Cost is a reported model-price estimate, not an invoice or actual subscription charge. External MCP billing is not estimated unless reported as native model usage.
- Per-run amounts use the latest cumulative usage snapshot. Repeated stream updates replace the amount instead of adding it again; final usage reconciles the estimate.
- The session total excludes the parent model's own responses. Native usage attributed to parent-MCP calls is included once, not duplicated through child usage.
- Totals follow all recorded entries in the current Pi session file, including abandoned branches and copied/forked history, consistent with Pi's session stats.
- Totals and recent results recover after reload/resume without restarting jobs or making model calls. Trimming old detail rows does not remove their cost.
The UI retains at most 64 finished details, 80 timeline events and 16 KiB of assistant text per run. A lightweight amount/ID ledger covers the whole session; results and amounts are reconstructed from existing Pi records. New metadata records bounded assignment text and usage so interrupted/final work can be identified. No separate billing service or credential store is used. Raw thinking, tool arguments and full tool-result payloads are not added to this UI store. Assignments/output can still contain sensitive data. Views unsubscribe and stop timers when closed.
In RPC/JSON/print mode, /agents returns a status/cost snapshot rather than opening
a terminal component. /native-agents [status] remains the compatibility summary;
/native-agents stop cancels all current and queued work.
The tool is model-only (not codemode-callable) and may run in parallel with other
parent tool calls. One FIFO scheduler shared by every task invocation caps active
children at 20 by default. All roles share the pool: 20 workers can run at once,
including repeated calls to the same worker definition. Excess work queues within
the configured queue limit; a batch may contain up to 20 assignments.
Ask: "Start 20 worker agents in parallel, one per independently assigned file."
Use repeated agent: "worker" entries in the tasks array, or separate task calls.
No unique role name is required for each instance.
Parallel workers share the workspace. Give them disjoint file ownership or isolated worktrees/branches; this package does not lock files, merge conflicts, or provide transactional edits. Native parent edits and inherited MCP mutations can also race. The scheduler limits concurrency, not write conflicts.
Twenty is a session limit, not guaranteed provider throughput. Model/MCP rate limits, CPU/memory, and quota may reduce effective parallelism. Twenty contexts can multiply token usage and cost. No provider restrictions are bypassed.
How MCP inheritance works
No extra configuration is required.
- Pi's MCP readiness hook can prepare the servers before delegation because
taskdeclares that it reaches other tools. - The parent snapshots its callable MCP tools at dispatch, including tools with deferred/codemode exposure and resource helper tools.
- Child Pi sessions register native tool proxies with the same names, schemas, namespace instructions, annotations, and structured output schemas.
- Calls go through the parent's public
ctx.executeTool(), preserving parent argument validation, MCP connections/authentication, permission/redaction hooks, nested-call events, and error results. - An authenticated 127.0.0.1-only bridge exists for the task batch and closes on completion, cancellation, or parent shutdown. Children never load builtin MCP.
This includes tools from user-level, trusted project, and extension/session-registered MCP servers when they are callable by that parent. It does not reconnect servers, enable disabled/hidden tools, export OAuth stores, or copy server credentials. Tool metadata and results necessarily cross into the child; complete server configs and the parent transcript do not.
Inheritance is a per-dispatch snapshot. Newly registered tools appear on the next delegation. The parent rechecks calls through its live tool pipeline, so withdrawal or permission changes can cause an inherited call to fail rather than bypass policy.
All roles inherit mutators too: an MCP tool being dangerous or marked non-read-only does not remove it. Parent permission checks can still block it. Role instructions and assignment scope remain important, but are not a sandbox.
MCP usage reported by nested parent calls is accounted by Pi's outer task result. It is not sent back through child tool usage and counted twice. Text, images, structured results, and explicit errors are forwarded. Tool progress remains visible through parent nested-call events; child progress identifies the active tool. The bridge limits request arguments to 4 MiB and results to 16 MiB, returning explicit errors rather than silently corrupting oversized content.
Migration from 0.1
Remove researchTools from personal/project native-agents.json.
Its presence now fails with a migration/config error rather than silently ignoring
an old restrictive allowlist. Researcher no longer needs a separate allowlist.
With no suitable parent search/fetch tool, researcher must disclose the evidence gap.
Research requests may consume quotas or incur costs. The research prompt asks for free routes unless spending is authorized, but this is not a technical dollar cap.
Models and budgets
With no override, children inherit the exact parent provider/model and thinking
level. Overrides must be exact provider/id, authenticated in the child and within
any parent model scope. There is no model fallback.
Create <agentDir>/native-agents.json (normally ~/.pi/agent/native-agents.json):
{
"allowProjectConfig": false,
"delegation": "auto",
"maxConcurrency": 20,
"maxQueued": 32,
"maxTasks": 20,
"timeoutMs": 300000,
"maxTurns": 30,
"outputBytes": 12000,
"resultBytes": 65536,
"agents": {
"scout": { "model": "your-provider/exact-model-id", "thinking": "low" },
"worker": { "thinking": "high" }
}
}
Omit a field to use the role definition/parent default; JSON null explicitly uses
the parent. Set disabled: true to hide a role.
Thinking: off, minimal, low, medium, high, xhigh, max; Pi clamps to model support.
- Up to 20 assignments per batch, at most 20 concurrent agents of any role.
- FIFO scheduling shares capacity across batches and single calls; workers are not exclusive.
- Lower
maxConcurrencyif your provider or machine cannot comfortably handle 20. - To retain the old serial-worker behavior, set
maxConcurrency: 1. - The deadline includes queueing and startup; cleanup adds a few seconds.
- The turn budget stops further tool loops, not an in-flight request.
- Children honor the user's existing Pi retry and compaction policies. The package does not toggle persisted global settings; task deadlines and turn budgets still apply.
outputBytesis the batch's approximate text budget, divided among children. Status, headings, and artifact paths add a small amount.resultBytescaps a retained answer, up to 256 KiB. Oversized handoffs are clipped safely for UTF-8 and link to private OS-temp files.- Output-token limits and retained-output clipping mark results
incomplete.
Results include IDs, status, effective model/thinking, time, usage, and errors or
truncation information. Unknown settings are errors; old settings.json.subagents
is not used. UI model/thinking saves update future calls immediately without
resetting the scheduler or current jobs. Direct file/budget edits require /reload.
Custom agents and trust
Markdown roles are loaded from bundled agents, then
<agentDir>/native-agents/agents/*.md.
Project roles at <cwd>/.pi/native-agents/agents/*.md and project config
<cwd>/.pi/native-agents.json load only with personal
"allowProjectConfig": true and parent project trust.
Project discovery is off by default. Pi can report a workspace trusted when no standard protected resources exist; opt-in authorizes discovery under that decision, not proof of individual file approval. Projects cannot enable this flag themselves.
---
name: architecture-reviewer
description: Review module boundaries
mode: read
tools: [read, grep, find, ls]
---
Inspect the assigned scope and report concrete problems with file references.
Frontmatter: name, description, mode, tools, model, thinking, research. Mode/tools restrict native capabilities. All custom agents also inherit parent MCP. The optional research flag describes a read-native research role; it no longer controls MCP inheritance. Duplicate names within a directory and unknown overrides are errors. Trusted project roles override personal roles by name.
Child process boundary
Children use the same installed Pi package's dist/cli.js via exported RpcClient,
an in-memory session, explicit tools, role prompt, and package-owned guard.
No ambient extensions, skills, templates, themes, context files, project settings,
or child MCP connections are loaded. Model/auth configuration is used by Pi itself;
custom provider extensions are not inherited and unsupported child models fail
without prompting. Standalone-only Pi executables are not supported in v0.6.
Native child file/shell tools do not inherit parent permission hooks. Inherited MCP calls do inherit those hooks through the parent pipeline. A recursion marker and restricted native loadouts prevent ordinary nested delegation; a hostile worker's shell can bypass prompt-level restrictions.
Read SECURITY.md. Separate contexts/processes are not OS sandboxes. Native read roles can read OS-accessible paths outside cwd; all roles may have remote mutating MCP capability. Foreground only: no detached jobs, durable resumption, worktrees, or automatic review loops.
Cancellation requests Pi abort then force-stops the child; commands that daemonize, or parent MCP implementations ignoring cancellation, may keep working. Private temp results may contain sensitive data; remove them when no longer needed. Policy files contain only tool metadata and an ephemeral local bridge capability, not MCP/provider credentials, and are removed during cleanup. OS cleanup can make result links stale. Parent session results retain child summaries/metadata. Pi's RPC client forwards normal child stderr; review logs before sharing them.
Tests and release
npm run check
npm run test:integration
npm pack
Unit tests need no dependency install. Integration tests use real Pi sessions, a loopback-only mock model API, and an offline stdio MCP fixture: no live providers or public web services. They exercise native reads, every role's inheritance of a session-registered MCP server (including mutators), parent permission blocking, cancellation, and the inspector. A barrier test runs 20 real worker RPC processes simultaneously and verifies 20 independent native file writes against an offline model. UI tests use real Pi SelectList/ScrollView and test mouse selection, keyboard navigation, empty states, scrolling/follow, individual stop, cleanup, Unicode, narrow terminals and resizing. They do not verify live provider entitlements or remote billing.
If Pi is not a resolvable local module:
PI_TEST_HOST=/path/to/@earendil-works/pi-coding-agent npm run test:integration
Without a host, integration cases are explicitly skipped. CI installs a pinned test host in an isolated job; the workflow file is not evidence remote CI has run.
Before publishing:
- Confirm npm ownership, version availability, maintainers, and private security reporting.
- Run checks and offline integration on the supported OS/Node matrix.
- Inspect
pi-native-agents-0.6.0.tgzand test loading the extracted archive. - Review the security implications of full parent MCP inheritance and all release files.
- Optionally perform explicitly approved live tests in a scratch project.
- Only after release approval: publish the reviewed archive with suitable 2FA/provenance, then tag the source.
No npm login or service credentials are included in this repository. The release allowlist excludes tests/fixtures, CI, development scripts, and machine config. Prepack runs offline release checks and unit tests.
Inspiration
Original package code using Pi's public APIs. References: Pi's official subagent example and OMP's focused-agent conventions. No OMP or pi-subagents source/runtime is bundled. Not an official Pi project.