pi-provider-utils

Shared provider mirror, stream, and agent-path helpers for Pi extension packages

Package details

package

Install pi-provider-utils from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:pi-provider-utils
Package
pi-provider-utils
Version
0.0.0
Published
Mar 27, 2026
Downloads
281/mo · 84/wk
Author
victor-founder
License
MIT
Types
package
Size
40.8 KB
Dependencies
0 dependencies · 2 peers

Security note

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

README

pi-provider-utils

Shared provider mirror, stream, and agent-path helpers for Pi extension packages.

Status

This package extracts duplicated helper code from pi-credential-vault and pi-multicodex into a single shared dependency. It provides generic provider and agent utilities — not vault-specific or multicodex-specific policy.

Current consumers:

  • @victor-software-house/pi-credential-vault
  • @victor-software-house/pi-multicodex

Current next steps:

  1. publish this package to npm
  2. switch consuming repos from link: to npm dependency
  3. adopt pnpm workspace and Turborepo once the published package is the common dependency boundary

Install

This package is a shared library, not a standalone Pi extension. Do not install it with pi install.

Consume it from another package instead:

{
  "peerDependencies": {
    "@victor-software-house/pi-provider-utils": "*"
  },
  "devDependencies": {
    "@victor-software-house/pi-provider-utils": "*"
  }
}

For local multi-repo development before publication, use a link: dev dependency:

{
  "devDependencies": {
    "@victor-software-house/pi-provider-utils": "link:../pi-provider-utils"
  }
}

Entrypoints

@victor-software-house/pi-provider-utils/providers

Provider mirror metadata and model-registry helpers.

import {
  mirrorProvider,
  listProviderIdsWithModels,
  type MirroredProvider,
  type MirroredModelDef,
} from "@victor-software-house/pi-provider-utils/providers";

// Mirror an existing provider's configuration for re-registration
const mirror = mirrorProvider("openai");

// List all provider IDs that have registered models
const ids = listProviderIdsWithModels();

@victor-software-house/pi-provider-utils/streams

Stream and error primitives for extension-owned provider wrappers.

import {
  normalizeUnknownError,
  createErrorAssistantMessage,
  pushErrorEvent,
  createImmediateErrorStream,
  pipeAssistantStream,
  rewriteProviderOnEvent,
  createLinkedAbortController,
  createTimeoutController,
} from "@victor-software-house/pi-provider-utils/streams";

// Normalize an unknown thrown value into a string
const msg = normalizeUnknownError(error);

// Create a stream that immediately emits an error
const stream = createImmediateErrorStream(model, "no credentials");

// Pipe events from one stream to another
await pipeAssistantStream(source, target);

// Rewrite the provider field on stream events
const rewritten = rewriteProviderOnEvent(event, "my-provider");

// Create an AbortController linked to a parent signal
const controller = createLinkedAbortController(parentSignal);

// Create a linked controller that auto-aborts after a timeout
const { controller: tc, clear } = createTimeoutController(signal, 30_000);

@victor-software-house/pi-provider-utils/agent-paths

Canonical ~/.pi/agent/* path helpers and JSON file I/O.

import {
  getAgentPath,
  getAgentSettingsPath,
  getAgentAuthPath,
  readJsonObjectFile,
  writeJsonObjectFile,
  ensureParentDir,
} from "@victor-software-house/pi-provider-utils/agent-paths";

// Resolve a path relative to ~/.pi/agent/
const vaultPath = getAgentPath("vault.age.json");

// Read and write JSON object files (sync)
const settings = readJsonObjectFile(getAgentSettingsPath());
settings["my-extension"] = { enabled: true };
writeJsonObjectFile(getAgentSettingsPath(), settings);

// Async variants are also available
import {
  readJsonObjectFileAsync,
  writeJsonObjectFileAsync,
} from "@victor-software-house/pi-provider-utils/agent-paths";

What this package does NOT contain

  • OAuth login or refresh orchestration
  • Quota classification or retry policy
  • Vault backend registry logic
  • Multicodex account selection logic
  • Footer rendering or settings-panel components

These belong in the owning extension packages (pi-credential-vault, pi-multicodex), not in shared utilities.

Development

pnpm install
pnpm typecheck
pnpm test
npm pack --dry-run

Validation status at extraction time:

  • 52 tests covering all three entrypoints
  • pnpm typecheck passes
  • npm pack --dry-run includes only the library contract and tests