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 request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions