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 3600 Prompt timeout (seconds)
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

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.2.tar.gz (62.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.2-py3-none-any.whl (82.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: soulacp-0.1.2.tar.gz
  • Upload date:
  • Size: 62.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.2.tar.gz
Algorithm Hash digest
SHA256 21cfcebe03adbef5ddc2932cf549a4c8a390d9647a7f103fc82239a30b86186c
MD5 1c51eae8f71b2114ecf9d1852ef41cbb
BLAKE2b-256 dd7cf850a28d9a4460935c9243dcba555afca85c67481622440b8fa6eac4d98c

See more details on using hashes here.

File details

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

File metadata

  • Download URL: soulacp-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 82.4 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.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b36944e65aee283ac9499f309c8f154ff9a3d2886165f814e9e0a05721f3b29e
MD5 bd3ffbe2269a0eb373d5acdf9b5449cc
BLAKE2b-256 adc776c7663c6d4d89eeb2896cbdb7269df943ac103bc02d57f4a3f187664faf

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