pi-agent-model-select

Select models and supported thinking for the current Pi session, project defaults and subagent roles

Packages

Package details

extension

Install pi-agent-model-select from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-agent-model-select
Package
pi-agent-model-select
Version
0.1.1
Published
Sep 6, 2026
Downloads
320/mo · 15/wk
Author
kanasho116
License
MIT
Types
extension
Size
38.3 KB
Dependencies
1 dependency · 2 peers
Pi manifest JSON
{
  "extensions": [
    "./index.js"
  ]
}

Security note

Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.

README

pi-agent-model-select

Choose target -> available model -> supported thinking with /agent-model. A small JavaScript Pi extension with no build step.

Version: this documentation describes 0.1.1. Check the npm registry for release availability. Version 0.1.0 supports session model/thinking selection and project role defaults, but does not save Main/All defaults for fresh main sessions in .pi/settings.json.

Installation

Requires Node.js 22.19+ and @earendil-works/pi-coding-agent 0.85.x. Project role behavior was checked against @tintinweb/pi-subagents 0.19.0; that extension must be installed separately to run those roles. Main-only use does not require it.

To install version 0.1.1 from your project root:

pi.cmd install -l npm:pi-agent-model-select@0.1.1
pi.cmd

This registers the npm package locally in .pi/settings.json, not in global Pi settings. Start a fresh Pi session after installation. Registry installation requires that version to be published; local checkout instructions are below.

Alternatively, install with npm directly and load the extension explicitly:

npm.cmd install pi-agent-model-select
pi.cmd -e ./node_modules/pi-agent-model-select/index.js

Direct npm installation adds a project dependency but does not register it in Pi settings. Use either registered loading or -e, not both.

Local Checkout

For local evaluation, from this checkout:

npm.cmd ci --ignore-scripts
pi.cmd -e ./index.js

To evaluate against another project without registering the package or changing settings, start Pi from that project's root and pass this extension's absolute index.js path to -e. Do not load two copies of the extension.

Usage

In Pi, enter:

/agent-model
  1. Choose All Agents, Main Agent, or a discovered role such as Scout Agent. Role labels include the original identity to distinguish similar names.
  2. Choose an authenticated/configured model from ctx.modelRegistry.getAvailable(). Each entry shows its readable name and provider/id.
  3. Choose a supported thinking level such as Off or High. Labels map to Pi's canonical values (off, high, etc.); nonreasoning models explain why only Off is offered.
  4. Confirm the exact settings/role file list before applying any selection, including Main. Project trust is required.

Later dialogs show a target/model breadcrumb. Current marks the main model; Current main on All Agents refers only to main, not every role. Current role marks a role's explicit provider/id default; inherited or fuzzy defaults are not guessed.

Back or Escape returns from thinking to models or from models to targets. Escape at the target menu, or Cancel at any menu, exits without applying a selection. Declining or escaping confirmation also exits. Dialog-capable UI (TUI or an RPC client implementing Pi dialogs) is required.

日本語クイックスタート

0.1.1 のインストールは、対象プロジェクトのルートで実行します。

pi.cmd install -l npm:pi-agent-model-select@0.1.1
pi.cmd

Pi で /agent-model を入力し、対象 → モデル → Thinking の順に選択します。 Scout Agent などの役割名は .pi/agents/*.md から自動検出されます。 役割ファイルへの保存には確認が必要で、設定は新しく起動する子エージェントに適用されます。 実行中・再開する子エージェントやグローバル設定は変更しません。 Back または Escape で前の選択に戻り、Cancel で終了します。 対象選択画面での Escape と保存確認のキャンセルも終了操作です。 組み込みの /model は変更しません。ソースから試す場合は上記 Local Checkout の手順を使用します。

Scope

Target Effect
Main Agent Calls pi.setModel, then pi.setThinkingLevel, checks readback, and saves project defaults in .pi/settings.json.
Project role Updates only model and thinking in that role's .pi/agents/*.md frontmatter. Main session unchanged.
All Agents Current main session and project defaults, plus every discovered .pi/agents/*.md role. Also saves defaults when there are no roles.

“All” does not mean every worker or every role installed on the machine. Global roles, built-in roles without a project override, .agents/agents, global settings, and active/resumed children are not changed. Disabled project role files are included but remain disabled. No roles are created. Main/All can create the trusted project's .pi directory and settings.json without .pi/agents. The command does not register tools, spawn children, reload sessions, or call private subagent APIs.

Main Defaults

Version 0.1.1 fixes Main selections being lost on a fresh launch: public extension setters only change session state, so Main/All additionally merge the documented project settings below (example):

{
  "defaultProvider": "provider",
  "defaultModel": "model-id",
  "defaultThinkingLevel": "high",
  "modelThinkingLevels": { "provider/model-id": "high" }
}

defaultModel is the model ID alone, not provider/id. The per-model entry is also necessary: an inherited per-model thinking preference outranks the default thinking level. Other settings, package registrations, and other per-model map entries are preserved. JSON formatting is normalized; malformed JSON or a non-object settings/thinking map is refused rather than replaced. Individual role selections never change these settings. No global settings are written, no private Pi writers are used, and no startup handler forces a restore.

These are defaults, not a guaranteed startup selection. Explicit CLI options such as --provider, --model, --thinking, and --models (including thinking suffixes), enabledModels scopes, or a resumed/continued session can override them. Untrusted project configuration is ignored by Pi; an unavailable model or missing authentication can cause fallback. Start from the same project root in a fresh trusted session without overriding flags to use the saved defaults. When ctx.scopedModels is nonempty, selections warn before confirmation and in the success message that --models/enabledModels may override startup model or thinking. The extension never widens or rewrites that scope, nor reads global auth files to diagnose it. A later built-in settings change may also supersede these defaults; the extension does not continuously enforce them.

Role identity uses the trimmed YAML name, falling back to the filename, just as pi-subagents does. Duplicate project identities and names containing its reserved : are rejected. Discovery happens each time the target menu opens. Pi-subagents 0.19.0 reloads definitions on each Agent call; saved values apply to new children, and frontmatter outranks model/thinking tool-call arguments. Existing/resumed workers keep their own session configuration. Isolated worktrees may not see uncommitted role changes. Other subagent implementations are not claimed to support this format.

Why Not /model?

/model is Pi's built-in command. Pi 0.85.0 handles it directly in interactive command dispatch; this extension cannot override it through the supported command registration API. /agent-model is the supported entry point. There is no terminal-input interception, editor replacement, or monkey-patching.

Safety and Persistence

  • Requires an idle main session and project trust for persistent changes. An unset main model is refused when changing main because it cannot be restored through setModel on failure.
  • Checks model availability and resolves authentication through getApiKeyAndHeaders before mutation, including the previous model when needed for rollback. This is not an inference request or proof credentials work remotely. Provider auth resolution may itself refresh credentials or run a configured auth helper; the extension never edits auth/global settings.
  • Uses the real supported-thinking helper, including custom thinking maps, xhigh/max where exposed, and only off for nonreasoning models. It does not guess capabilities from model names. The menu uses the available registry, not the narrower --models/enabledModels cycling scope.
  • Parses YAML with yaml, then edits source ranges instead of serializing the document. Unrelated fields, comments, BOM, LF/CRLF, and prompt bytes remain intact. Missing frontmatter/keys are inserted; model IDs are stored as quoted provider/id strings. Invalid UTF-8, malformed/duplicate YAML keys, root flow maps, aliases, anchors, explicit tags, merge/complex keys and block-style model/thinking values are refused. Simplify such frontmatter manually first. Ambiguous fence prefixes such as ---custom: keep before the closing fence are also refused: Pi stops at the first newline followed by ---, even if it looks like a YAML key. Text after a valid closing fence remains untouched. Invalid project files fail discovery closed, including for the main menu.
  • Rejects symlinks/junctions in the project path, symlink/nonregular/hard-linked settings/role files, escaped paths, stale file identities/content/metadata, and changed All-target role sets. Opens all target files for writing before changing main.
  • Uses an exclusive .pi/.agent-model-select.lock to serialize cooperating package instances. An existing lock is never removed automatically. After a crash, inspect the files and ensure no operation is running before manually removing a stale lock.
  • Settings participate in the same conflict checks, disk readback and rollback as roles. New settings use exclusive wx creation; failed operations remove that file only when its identity and bytes still belong to this transaction. A newly created empty .pi directory may remain after failure. Do not run 0.1.0 and 0.1.1 concurrently: the older version used a role-directory lock.
  • Holds file descriptors, rechecks paths/content, performs the final file writes synchronously, and flushes them. On failure it attempts to restore its own changes in reverse order, but refuses to overwrite detected concurrent edits. PARTIAL errors identify files or main-session state that could not safely be restored. Lock cleanup failures are reported even if settings were applied.

These guards are not an OS sandbox or an atomic multi-file transaction. Node's portable filesystem API has no compare-and-swap write: an uncooperative process can race the final check/write, and a crash/power loss can leave partial in-place writes. Do not edit settings/roles or switch sessions concurrently with this command. The main setter can trigger other extensions' model-select handlers; their side effects and session transcript entries cannot be undone. A successful rollback restores effective values, not history. There is no automatic retry or crash-recovery journal. Keep settings and role files under version control.

Development

npm.cmd ci --ignore-scripts
npm.cmd test
npm.cmd run pack:check
npm.cmd pack

On non-Windows systems use npm and pi instead of their .cmd forms. Tests use only node:test and built-in assertions/mocks; no transpiler or test dependency. Fixtures stay under the checkout's ignored .test-tmp directory and are cleaned after each test. Coverage includes byte preservation, YAML rejection, path guards, auth, cancellation/Back/confirmation, supported thinking, role discovery, concurrent changes, injected write failures and safe rollback. CI runs Node 22/24 on Windows/Linux: npm ci --ignore-scripts, npm test, npm run test:host, and npm run pack:check, sequentially. For the host check, CI installs exactly Pi 0.85.0 and pi-server 0.85.1 in a separate runner-temp prefix with lifecycle scripts disabled and no saved dependency or lockfile changes. PI_TEST_HOST points to that prefix's node_modules/@earendil-works/pi-coding-agent on both platforms. Pi 0.85.0's SDK entry point imports pi-server without installing it; the explicit server package matches the verified local host workaround. It is not a new runtime dependency of this extension. CI never publishes.

The host check is mandatory in CI and before release. Locally it uses an already installed Pi 0.85.0 host, without adding test dependencies or installing this extension:

$env:PI_TEST_HOST = 'C:\path\to\node_modules\@earendil-works\pi-coding-agent'
npm.cmd run test:host

This calls actual SettingsManager.create and createAgentSession in fresh instances with an isolated agent directory, in-memory credentials/model cache and sessions, fake models, and no loaded resources or inference. It checks Main and All defaults before any assistant message, including an inherited conflicting thinking preference and untrusted settings behavior. It does not use the user's auth files or settings. Run separately from npm test; it requires the host path.

The public files allowlist is index.js, core.js, README.md, LICENSE, plus npm's mandatory package.json. pack:check runs a real offline npm pack --ignore-scripts in a unique temporary directory under .test-tmp, checks npm's manifest and the actual tar archive against that exact allowlist, extracts it, and ESM-imports the shipped entry point with a command-registration stub. It also verifies that each missing file is rejected using disposable extracted copies. It uses Node built-ins plus npm and tar (required on PATH), resolves existing checkout dependencies, and cleans its temporary artifacts even on failure. It does not install, access the network, load user Pi config, or exercise the real Pi loader. Lifecycle scripts are skipped internally to avoid recursive prepack/test runs; CI runs tests separately and prepack runs tests for normal packing. The lockfile pins development/CI resolution; npm consumers resolve the declared dependency/peer ranges.

API evidence for the initial implementation: Pi 0.85.0 dist/core/extensions/types.d.ts, dist/core/model-registry.d.ts, dist/core/agent-session.js, and interactive /model dispatch; Pi AI 0.85.0 dist/models.js; pi-subagents 0.19.0 src/custom-agents.ts, src/model-resolver.ts, and src/invocation-config.ts. The 0.1.1 persistence check also uses Pi 0.85.0 settings-manager, sdk, and model-runtime public APIs. The extension itself only writes project JSON.

License

MIT. Copyright (c) 2026 KANAsho116.

Release Checks

The package targets public access at https://registry.npmjs.org. All checks below are mandatory before publishing:

  1. Pass npm test, then npm run test:host against Pi 0.85.0 with PI_TEST_HOST set as above. Do not run these concurrently in the shared checkout.
  2. Pass npm run pack:check and the Node 22/24 Windows/Linux CI matrix.
  3. Perform a real interactive/authenticated Main, All, and new-child smoke test: verify provider inference, fresh trusted main-session defaults (without CLI overrides), and saved model/thinking on newly spawned project roles. Check cancellation and confirm existing/resumed children remain unchanged.
  4. Verify npm package ownership/access and intended version, review the final archive from npm pack (which runs prepack tests), and update release status only when the release is actually published.

Offline SDK tests and ESM registration checks do not establish provider connectivity, actual Pi extension-loader behavior, or real child execution. There is no automatic publishing; authenticated smoke checks require a separate, explicitly authorized environment and are not performed by CI.

For 0.1.1, the maintainer reported successful completion of the authenticated checks above on 2026-09-06. This is maintainer-reported manual evidence, not an automated inference test result.