Skip to main content

Python ACP client library — connect to 29 AI coding agents with zero session overhead

Project description

soulacp

CI Python License

Python ACP client library — connect to AI coding agents with zero session overhead.

Features

  • 29 CLI adapters: Claude Code, Gemini, OpenCode, OpenClaw, Cursor, Codex, Qwen, Kimi, Codebuddy, Cline, Copilot, Minion, Vibe, Nova, Crow, Amp, Auggie, Autohand, Corust, DeepAgents, Factory Droid, fast-agent, Copilot LS, Goose, Junie, Kilo, pi ACP, Qoder, Stakpak
  • No own session layer: Directly manages CLI's native session
  • Zero token overhead: No middleware, no duplicate session history
  • ManagedSession: High-level API with auto session reuse, rotation, retry, fallback
  • Connection pooling: Reuse idle connections, session matching
  • Session store: Persistent user→session mapping with TTL (Memory or File cache)
  • Async streaming: Real-time response chunks via asyncio
  • Auto-retry: Exponential backoff with jitter
  • Host services: Built-in file system and terminal services for CLI tool calls
  • Pure stdlib: No external dependencies

Install

pip install soulacp

Quick Start

ManagedSession (recommended)

import asyncio
from soulacp import ManagedSession

async def main():
    async with ManagedSession(provider="claude", model="claude-sonnet-4-20250514") as session:
        # Simple query — session auto-managed
        response = await session.query("Hello!", user_id="user1")
        print(response)

        # Streaming
        async for chunk in session.stream("Write hello world", user_id="user1"):
            print(chunk, end="", flush=True)

asyncio.run(main())

ManagedSession automatically handles:

  • Session reuse: Same user_id gets same CLI session across requests
  • Session rotation: Fresh session on "prompt too long" overflow
  • Retry: Exponential backoff on transient errors
  • Fallback: Switch to alternate provider on persistent failure

Low-level API

import asyncio
from soulacp import ACPConfig, ACPConnectionPool, resolve_client_class

async def main():
    config = ACPConfig(provider="claude", model="claude-sonnet-4-20250514")
    client_class = resolve_client_class("claude")
    pool = ACPConnectionPool(config, client_class)

    async with pool.acquire() as (client, session_id):
        response = await client.query("Hello!")
        print(response)

    await pool.close_all()

asyncio.run(main())

Supported Agents

Agent Provider Model Example CLI Command
Claude Code claude claude-sonnet-4-20250514 claude or claude-code-acp
Gemini gemini gemini-3-flash-preview gemini --acp
OpenCode opencode opencode acp
OpenClaw openclaw openclaw acp
Cursor (ACP) cursor cursor-acp/default cursor-agent acp
Cursor (Legacy) cursor-cli cursor-cli/gpt-4 cursor-agent -p
Codex codex codex-acp/gpt-5 codex-acp
Qwen Code qwen qwen-acp/qwen-coder qwen-code --acp --experimental-skills
Kimi CLI kimi kimi-acp/default kimi acp
Codebuddy Code codebuddy codebuddy-acp/default codebuddy-code --acp
Cline cline cline-acp/default cline --acp
GitHub Copilot copilot copilot-acp/default copilot --acp
Minion Code minion minion-acp/default minion-code acp
Mistral Vibe vibe vibe-acp/default vibe-acp
Nova nova nova-acp/default nova acp
Crow CLI crow crow-acp/default crow-cli acp
Amp amp amp-acp/default amp-acp
Auggie auggie auggie-acp/default auggie --acp
Autohand autohand autohand-acp/default autohand-acp
Corust Agent corust corust-acp/default corust-agent-acp
DeepAgents deepagents deepagents-acp/default deepagents-acp
Factory Droid droid droid-acp/default droid exec --output-format acp
fast-agent fastagent fastagent-acp/default fast-agent-acp -x
Copilot LS copilot-ls copilot-ls-acp/default copilot-language-server --acp
Goose goose goose-acp/default goose acp
Junie junie junie-acp/default junie --acp=true
Kilo kilo kilo-acp/default kilo acp
pi ACP pi pi-acp/default pi-acp
Qoder qoder qoder-acp/default qodercli --acp
Stakpak stakpak stakpak-acp/default stakpak acp

Usage

Claude Code

import asyncio
from soulacp import ManagedSession

async def main():
    async with ManagedSession(provider="claude", model="claude-sonnet-4-20250514") as session:
        response = await session.query("Hello!")
        print(response)

asyncio.run(main())

Gemini

import asyncio
from soulacp import ManagedSession

async def main():
    async with ManagedSession(provider="gemini", model="gemini-3-flash-preview") as session:
        response = await session.query("Hello!")
        print(response)

asyncio.run(main())

Multi-Agent

import asyncio
from soulacp import ManagedSession

async def main():
    # Claude for code generation
    async with ManagedSession(provider="claude", model="claude-sonnet-4-20250514") as claude:
        code = await claude.query("Write a sorting algorithm in Python")

    # Gemini for code review
    async with ManagedSession(provider="gemini", model="gemini-3-flash-preview") as gemini:
        review = await gemini.query(f"Review this code:\n{code}")

asyncio.run(main())

Session Management

ManagedSession + ProviderSessionStore

ManagedSession uses ProviderSessionStore internally to map (user_id, provider) to CLI session IDs:

from soulacp import ManagedSession

session = ManagedSession(provider="claude", model="claude-sonnet-4-20250514")

# First request — creates new CLI session, stores mapping
await session.query("Remember 42.", user_id="alice")

# Second request — reuses same CLI session (alice→session_abc)
await session.query("What number?", user_id="alice")

# Different user — gets different CLI session
await session.query("Hello!", user_id="bob")

Custom Session Store

from soulacp import ManagedSession, ProviderSessionStore, FileCache

# Persistent file-based session store
store = ProviderSessionStore(cache=FileCache("~/.soulacp/sessions.json"))
session = ManagedSession(provider="claude", model="claude-sonnet-4-20250514", session_store=store)

Session Lifecycle

Event Behavior
First request New CLI session created, mapping stored (TTL 7 days)
Subsequent requests Same user_id → same CLI session (reuse)
"Prompt too long" Auto-rotate to fresh session, clear old mapping
Connection error Clear mapping, retry with new session
Fallback Switch to alternate provider (e.g. claude→gemini)

Cache Backends

from soulacp import MemoryCache, FileCache

# In-memory (default) — fast, lost on restart
memory = MemoryCache(max_size=10000)

# File-based — persists across restarts
file_cache = FileCache("~/.soulacp/sessions.json", debounce_seconds=1.0)

Low-level Session Control

from soulacp import ACPConnectionPool, ACPConfig, resolve_client_class

config = ACPConfig(provider="claude", model="claude-sonnet-4-20250514")
pool = ACPConnectionPool(config, resolve_client_class("claude"))

# Explicit session reuse
async with pool.acquire() as (client, sid):
    await client.query("Remember 42.")

async with pool.acquire(session_id=sid) as (client, sid2):
    assert sid2 == sid  # Same CLI session
    response = await client.query("What number?")

Configuration

Environment Variables

Variable Default Description
ACP_PROVIDER Provider name
ACP_MODEL Model identifier
ACP_POOL_SIZE 10 Max pool connections
ACP_TIMEOUT_CONNECT 30 Connection timeout (seconds)
ACP_TIMEOUT_PROMPT 2592000 Prompt timeout (seconds, 30 days)
ACP_TIMEOUT_STREAM 2592000 Stream chunk timeout (seconds, 30 days)
ACP_POOL_IDLE_TIMEOUT 2592000 Pool idle timeout (seconds, 30 days)
ACP_AUTO_APPROVE true Auto-approve tool permissions
ACP_MAX_RETRIES 3 Max retry attempts

Programmatic

from soulacp import ACPConfig

config = ACPConfig(
    provider="claude",
    model="claude-sonnet-4-20250514",
    pool_size=5,
    timeout_connect=60,
    auto_approve_permissions=True,
    enable_fallback=True,
)

From Environment

from soulacp import ACPConfig

config = ACPConfig.from_env()

Architecture

ManagedSession (high-level API)
  ├── ProviderSessionStore (user→session mapping)
  │   └── CacheBackend (MemoryCache / FileCache)
  ├── ACPConnectionPool (connection reuse + health check)
  │   └── ACPClientBase (JSON-RPC over stdio subprocess)
  │       ├── ClaudeACPClient      ├── ClineACPClient
  │       ├── GeminiACPClient      ├── CopilotACPClient
  │       ├── OpenCodeACPClient    ├── MinionACPClient
  │       ├── OpenClawACPClient    ├── VibeACPClient
  │       ├── CursorACPClient      ├── NovaACPClient
  │       ├── CodexACPClient       ├── CrowACPClient
  │       ├── QwenACPClient        └── CursorCLIClient (legacy)
  │       ├── KimiACPClient
  │       └── CodebuddyACPClient
  └── Services
      ├── FSService (file system operations)
      └── TerminalService (subprocess execution)

Testing

# Unit tests (no CLI required)
pytest tests/ --ignore=tests/test_integration*.py -v

# Integration tests (requires specific CLI installed, auto-skips if not available)
pytest tests/test_integration.py -v          # Claude Code
pytest tests/test_integration_gemini.py -v   # Gemini
pytest tests/test_integration_codex.py -v    # Codex

# All tests
pytest tests/ -v

AIXP Labs aixp.dev

AIXP Labs develops and maintains the following core projects:

Project Description Website
HSAW Human Sovereignty and Wellbeing — Axiom 0 white paper (foundation) hsaw.dev
AILP AI List Protocol — agent discovery and capability advertising ailp.dev
AIVP AI Value Protocol — international commerce, crypto asset settlement aivp.dev
AIRP AI RMB Protocol — Mainland China commerce, RMB licensed settlement airp.dev
AIBP AI Bot Protocol — social communication and trust aibp.dev
AIAP AI Application Protocol — governance and compliance aiap.dev
AISOP AI Standard Operating Protocol — flow program definition aisop.dev
SoulBot AI agent runtime and framework soulbot.dev
SoulACP Adapter library — bridging CLI tools and LLM providers (this project) soulacp.dev

⚠️ Disclaimer

This software is experimental and provided for research and educational purposes only. Not intended for production use. Use at your own risk. The authors assume no liability for any damages arising from the use of this software. See LICENSE for full terms (Apache 2.0).

License

Apache License 2.0 - Copyright 2026 AIXP Labs AIXP.dev | SoulACP.dev


Align Axiom 0: Human Sovereignty and Wellbeing. Version: SoulACP V0.1.2. www.soulacp.dev

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

soulacp-0.1.4.tar.gz (66.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

soulacp-0.1.4-py3-none-any.whl (84.9 kB view details)

Uploaded Python 3

File details

Details for the file soulacp-0.1.4.tar.gz.

File metadata

  • Download URL: soulacp-0.1.4.tar.gz
  • Upload date:
  • Size: 66.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for soulacp-0.1.4.tar.gz
Algorithm Hash digest
SHA256 7c955d4e31b5fb18202ba698c18d90dbf064d1fdb68e0678b7ca47a0136b381f
MD5 e611b1f617aecff845171a2e03d3752b
BLAKE2b-256 31cd0e714c96ce72e33752a3df25563c4681f40fdfd5c2762c443417cf4543c0

See more details on using hashes here.

File details

Details for the file soulacp-0.1.4-py3-none-any.whl.

File metadata

  • Download URL: soulacp-0.1.4-py3-none-any.whl
  • Upload date:
  • Size: 84.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.9

File hashes

Hashes for soulacp-0.1.4-py3-none-any.whl
Algorithm Hash digest
SHA256 8e2b4d8fa22dd77e9cfa99444c3bfac5fd1dcd4eba3095c4f864fa3403cc8819
MD5 e81a06f021b3d4649053301b85a7d2f0
BLAKE2b-256 4443cc8535ab44a341a457ad9de2856d1a91aaaf1a904520f0e9a47f974ac535

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page