Skip to content

refactor(pi-coding-agent): migrate from CLI subprocess to @mariozechner/pi-coding-agent SDK #704

@christso

Description

@christso

Problem

The pi-coding-agent provider currently spawns the Pi CLI as a subprocess and parses its JSONL stdout. This has several drawbacks:

  • Requires an executable path in every target config (e.g. executable: ${{ PI_CLI_PATH }})
  • JSONL parsing is fragile — tool calls must be reconstructed from raw JSON strings
  • The dead pi-agent-sdk provider (marked deprecated in feat(skill-trigger): multi-provider detection + workspace-scoped skills #702) bundles @mariozechner/pi-agent-core and @mariozechner/pi-ai as real package dependencies, causing upstream npm install warnings for all agentv users

Proposed Solution

Replace the subprocess approach with a direct call to @mariozechner/pi-coding-agent SDK. The package already exports everything needed:

// From @mariozechner/pi-coding-agent
import { createAgentSession, codingTools } from '@mariozechner/pi-coding-agent';
import { getModel } from '@mariozechner/pi-ai';

const { session } = await createAgentSession({
  cwd,
  model: getModel(provider, modelId),
  tools: codingTools,  // [read, bash, edit, write]
});

session.subscribe((event) => {
  // tool_execution_start, tool_execution_end, message_end — same as pi-agent-sdk
});

await session.prompt(prompt);

Tool calls come out in { type: 'toolCall', name: 'read', arguments: { path } } format — matching what PI_CODING_AGENT_MATCHER in the skill-trigger evaluator already expects.

Steps

  1. Add @mariozechner/pi-coding-agent as a dependency in packages/core/package.json and apps/cli/package.json
  2. Rewrite packages/core/src/evaluation/providers/pi-coding-agent.ts to use createAgentSession + event subscription instead of spawn + JSONL parsing. Preserve all existing config fields except executable (no longer needed)
  3. Remove pi-agent-sdk provider entirely:
    • Delete packages/core/src/evaluation/providers/pi-agent-sdk.ts
    • Remove registry entry from packages/core/src/evaluation/providers/index.ts
    • Remove PiAgentSdkResolvedConfig + pi-agent-sdk kind from packages/core/src/evaluation/providers/targets.ts and types.ts
    • Remove pi-agent-sdk entry from packages/core/src/evaluation/evaluators/skill-trigger.ts
    • Delete pi-agent-sdk tests
  4. Remove @mariozechner/pi-agent-core and @mariozechner/pi-ai as direct dependencies (they become transitive via pi-coding-agent)
  5. Drop executable field from PiCodingAgentResolvedConfig in targets.ts and update example targets.yaml files accordingly
  6. Update .agentv/targets.yaml and examples/features/.agentv/targets.yaml to remove executable field

Config Before / After

Before:

- name: pi
  provider: pi-coding-agent
  executable: ${{ PI_CLI_PATH }}
  pi_provider: openrouter
  model: openai/gpt-5.4
  api_key: ${{ OPENROUTER_API_KEY }}
  tools: read,bash,edit,write

After:

- name: pi
  provider: pi-coding-agent
  pi_provider: openrouter
  model: openai/gpt-5.4
  api_key: ${{ OPENROUTER_API_KEY }}
  tools: read,bash,edit,write

Key Files

File Change
packages/core/src/evaluation/providers/pi-coding-agent.ts Full rewrite: spawncreateAgentSession
packages/core/src/evaluation/providers/pi-agent-sdk.ts Delete
packages/core/src/evaluation/providers/index.ts Remove pi-agent-sdk registration, remove TODO comment
packages/core/src/evaluation/providers/targets.ts Remove executable from config type, remove PiAgentSdkResolvedConfig
packages/core/src/evaluation/providers/types.ts Remove pi-agent-sdk from ProviderKind
packages/core/src/evaluation/evaluators/skill-trigger.ts Remove pi-agent-sdk matcher entry
packages/core/package.json Add @mariozechner/pi-coding-agent, remove @mariozechner/pi-agent-core + @mariozechner/pi-ai
apps/cli/package.json Same dependency changes
examples/features/.agentv/targets.yaml Remove executable field
.agentv/targets.yaml Remove executable field

Notes

  • pi-utils.ts (extractPiTextContent, toFiniteNumber) and pi-log-tracker.ts are shared utilities — keep them unless the SDK's event model makes them redundant
  • The tools config field stays (maps read,bash,edit,write string → createCodingTools() etc.)
  • Skill detection via PI_CODING_AGENT_MATCHER in skill-trigger.ts requires no changes — tool call format is identical
  • The thinking config field maps to thinkingLevel in createAgentSession
  • Breaking change: executable is removed from config. Any user targets using executable will need to drop the field.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestin-progressClaimed by an agent — do not duplicate work

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions