@sage-protocol/pi-adapter

Sage Protocol MCP integration for pi coding agent

Packages

Package details

extension

Install @sage-protocol/pi-adapter from npm and Pi will load the resources declared by the package manifest.

$ pi install npm:@sage-protocol/pi-adapter
Package
@sage-protocol/pi-adapter
Version
0.4.1
Published
Aug 23, 2026
Downloads
202/mo · 36/wk
Author
hack4kites
License
MIT
Types
extension
Size
330.5 KB
Dependencies
1 dependency · 2 peers
Pi manifest JSON
{
  "extensions": [
    "./extensions"
  ]
}

Security note

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

README

@sage-protocol/pi-adapter

Sage integration for the Pi coding agent runtime.

  • Pi agent: earendil-works/pi — extensible terminal coding harness
  • Compatibility: tested with Pi 0.84.1; package peer range >=0.64.0 <0.85.0
  • Sage Protocol: sage-protocol/sage — decentralized capability/library layer for AI agents

What It Does

  • Exposes Sage MCP tools (hub_list_servers, hub_status, hub_session_list, hub_start_server, hub_stop_server, sage_search, sage_execute, sage_status, and sage_behavior)
  • Lets Pi own skill discovery and loading through native <available_skills>, /skill:<name>, and full SKILL.md reads
  • Injects SessionStart Sage context and shows the loaded library/skill inventory
  • Captures prompts and responses for RLM feedback
  • Observes truthful full native skill loads and writes source- and session-qualified load receipts
  • Exposes sage_mark_guided_use in the packaged Pi extension so an agent can bind actually loaded, actually applied skills to the exact prompt capture through Sage's native-use daemon path
  • Preserves optional security hooks and explicit subagent skill resolution
  • Keeps Sage-owned skills under packages/sage/skills/ and the curated Pi export surface rather than bundling copies in this adapter

The adapter does not call sage suggest hook skill for each prompt, inject sage-suggested-skills, or render a suggestion-quality widget. It has no suggestion auto-skip or auto-reject lifecycle. Manual sage suggest skill "<task>" remains available when a person or agent explicitly wants CLI ranking, but it is not automatic Pi injection.

Install

# Pi CLI extension (no source changes)
pi install npm:@sage-protocol/pi-adapter

# SDK embedding
npm install @sage-protocol/pi-adapter

Quick Start

import {
  createAgentSession,
  createCodingTools,
  type ToolDefinition as PiToolDefinition,
} from '@earendil-works/pi-coding-agent';
import {
  createSageSessionConfig,
  type ToolDefinition as SageToolDefinition,
} from '@sage-protocol/pi-adapter';

function asPiCustomTools(tools: SageToolDefinition[]): PiToolDefinition[] {
  // Type-shape compatibility across supported Pi minors; no runtime conversion.
  return tools as unknown as PiToolDefinition[];
}

const sage = await createSageSessionConfig({ source: 'pi-agent-core' });
const cwd = process.cwd();
const securedTools = sage.wrapToolsWithSecurity(createCodingTools(cwd));
const { session } = await createAgentSession({
  cwd,
  noTools: 'builtin',
  customTools: asPiCustomTools([...securedTools, ...sage.customTools]),
});
const disposeSageHooks = sage.setupHooks(session);

In current Pi, tools is a string allowlist. Tool definitions belong in customTools; noTools: 'builtin' prevents duplicate unwrapped built-ins. The single helper cast is only the TypeScript peer-version boundary between the adapter's cross-minor tool shape and Pi's generic ToolDefinition—it does not convert anything at runtime.

Pi presents its native skill catalog separately. When a skill applies, load it with /skill:<name> or read its complete SKILL.md, follow the procedure, then call sage_mark_guided_use only if the loaded procedure actually guided the current turn. Loading alone is not use.

API

createSageSessionConfig(config) returns:

{
  customTools: ToolDefinition[];           // Sage hub and code-mode bridge tools
  mcpBridge: SageMcpBridge;                 // MCP process lifecycle
  setupHooks: (session: AgentSession) => () => void;  // SessionStart + capture hooks
  wrapToolsWithSecurity: (tools: ToolDefinition[]) => ToolDefinition[];
}

Recommended configuration:

interface SageP2Config {
  sageBin?: string;           // default: "sage"
  sageProfile?: string;       // Sage config profile
  timeoutMs?: number;         // default: 20_000
  enableRlmFeedback?: boolean;
  enableSecurityHooks?: boolean;
  source?: string;            // default: "pi"
  env?: Record<string, string>;

  /** @deprecated Low-level legacy suggestion compatibility; ignored by the default Pi path. */
  suggestLimit?: number;
  /** @deprecated Low-level legacy suggestion compatibility; ignored by the default Pi path. */
  suggestDebounceMs?: number;
  /** @deprecated Low-level legacy suggestion compatibility; ignored by the default Pi path. */
  enableProvision?: boolean;
}

Migrating to 0.4

Version 0.4 moves Pi skill discovery and loading to Pi's native skill surface. The legacy sageInjectSuggestion(...) method is retained as a no-op for compatibility, and default setup no longer performs automatic suggestions. Do not call sageInjectSuggestion; use Pi's native skill load flow and call sage_mark_guided_use after an actually loaded skill guides the current prompt.

Docs

Validate

npm test
npm run typecheck
npm run build
git diff --check

License

MIT