Skip to main content

Official Python SDK for building and deploying agents on the Circuit platform

Project description

🚀 Agent SDK (Python)

A simple Python SDK for building cross-chain agents

PyPI version Python Version License: MIT

A Python SDK for building automated agents to deploy on Circuit. Features an incredibly simple API surface with just 2 main methods.

💡 Best used with Circuit Agents CLI - Deploy, manage, and test your agents with ease

📖 SDK Philosophy

This SDK is built on a low-level first approach:

  1. Core Functionality: At its heart, the SDK provides sign_and_send() - a single, powerful method that accepts any pre-built transaction for any supported network. This gives you complete control over transaction construction.

  2. Bring Your Own Tools: For production agents, we recommend using:

    • Solana: Use solana-py, solders, or anchorpy for transaction construction
    • EVM: Use web3.py or eth-account for transaction building
    • RPC: Make your own RPC calls for complex queries and custom needs

✨ Features

  • 🎯 Simple API: Only 2 main methods - add_message() and sign_and_send()
  • 🔒 Type Hinting: Network parameter determines valid request shapes automatically
  • 🚀 Cross-Chain: Unified interface for EVM and Solana networks
  • ⚡ Low-Level Control: sign_and_send() accepts any pre-built transaction
  • 🛠️ Smart Deployment: The agent wrapper detects its environment and exposes the necessary endpoints and handlers so you can focus on execution logic and easily test locally via our CLI tool

🚀 Quick Start

Install the SDK

pip install circuit-agent-sdk
# or with uv
uv pip install circuit-agent-sdk

Sample usage

Tip: Use the cli tool to spin up a sample agent, simple run 'circuit agent init' and select the python option. This will give you a fully functioning agent that will send a sample message. Simply plug in your execution logic, we will handle the rest.

"""
Circuit Agent - Python SDK Example

This demonstrates how to use the Circuit Agent Python SDK to create
an agent that can run locally via FastAPI and deploy to AWS Lambda.
"""

from agent_sdk import (
    Agent,
    AgentRequest,
    AgentResponse,
    AgentSdk,
    SDKConfig,
    setup_logging,
)

# Set up logging
logger = setup_logging()
logger.info("Python Agent SDK module loaded - executing main.py")


async def execution_function(request: AgentRequest) -> AgentResponse:
    """
    Main execution function for the agent.

    This function demonstrates proper usage of the Circuit Agent SDK with
    the new clean API using add_message() and sign_and_send().

    Args:
        request: Validated request containing sessionId,
                sessionWalletAddress, and otherParameters

    Returns:
        AgentResponse: Validated response indicating success/failure
    """
    # Create SDK instance with the session ID from the request
    sdk = AgentSdk(
        SDKConfig(session_id=request.sessionId, verbose=True)  # Enable debug logging
    )

    try:
        # Send observation message
        await sdk.add_message(
            {
                "type": "observe",
                "short_message": f"Python SDK Agent - Checking balance for {request.sessionWalletAddress[:8]}...",
            }
        )

        # Example transaction (commented out for safety)
        # result = await sdk.sign_and_send({
        #     "network": "ethereum:1",
        #     "request": {
        #         "to_address": request.sessionWalletAddress,
        #         "data": "0x",
        #         "value": "100000000000000000"  # 0.1 ETH
        #     },
        #     "message": "Self-transfer demo"
        # })

        # Return success response
        return AgentResponse(success=True, message="Execution completed")

    except Exception as error:
        logger.error(f"Error in agent execution: {error}")

        try:
            # Send error message to user
            await sdk.add_message(
                {
                    "type": "error",
                    "short_message": f"Agent execution error: {str(error)}",
                }
            )
        except Exception as msg_error:
            logger.error(f"Failed to send error message: {msg_error}")

        return AgentResponse(success=False, error=str(error))


async def stop_function(request: AgentRequest) -> AgentResponse:
    """
    Agent stop/cleanup function.

    This function is called when an agent session is being stopped.
    Use this to perform any necessary cleanup operations.

    Args:
        request: Validated request containing sessionId, sessionWalletAddress, and otherParameters

    Returns:
        AgentResponse: Validated response indicating cleanup success/failure
    """
    # Create SDK for cleanup operations
    sdk = AgentSdk(SDKConfig(session_id=request.sessionId))

    try:
        # Notify about cleanup
        await sdk.add_message(
            {
                "type": "observe",
                "short_message": f"Agent session {request.sessionId} stopping...",
            }
        )

        return AgentResponse(success=True, message="Cleanup completed")

    except Exception as error:
        logger.error(f"Error in stop function: {error}")
        return AgentResponse(success=False, error=str(error))


# NOTE: Everything below this should remain unchanged, unless you want to
# customize the agent configuration. This setup ensures you can run the agent
# locally and in the Circuit platform without any changes.

# Create the agent (configuration read from pyproject.toml)
agent = Agent(execution_function=execution_function, stop_function=stop_function)

# Export the Lambda handler for AWS deployment
handler = agent.get_lambda_handler()

# Local development server
if __name__ == "__main__":
    logger.info("Starting Circuit Agent development server...")
    logger.info(
        "The agent will automatically log available endpoints and example usage"
    )

    # Start the server for local development
    agent.run()

🎯 Core API (Only 2 Methods!)

The SDK is designed around just two main methods that cover all agent interactions:

1. Add Messages to Timeline

Use this for all agent communication and observability

await sdk.add_message({
    "type": "observe",
    "short_message": "Starting swap operation"
})

# Long messages are automatically truncated to 250 characters (when using dict input)
await sdk.add_message({
    "type": "observe",
    "short_message": "This is a very long message that will be automatically truncated if it exceeds 250 characters to prevent validation failures and ensure the message gets through successfully"
})

# Note: Pydantic models must be valid when created (max 250 chars)
# Dict inputs are automatically truncated by the SDK

## ✂️ Smart Message Truncation

The SDK automatically handles long messages to prevent validation failures:

```python
# Long messages are automatically truncated to 250 characters
await sdk.add_message({
    "type": "error",
    "short_message": "This is a very long error message that contains a lot of details and would normally cause validation to fail because it exceeds 250 characters, but the SDK automatically truncates it and adds '...' to indicate truncation, ensuring your message gets through successfully"
})

# Result: Message is truncated to 250 chars with "..." suffix
# This prevents the common error: "String should have at most 250 characters"

How it works:

  • Dict inputs: Automatically truncated before validation
  • Pydantic models: Must be valid when created (max 250 chars)
  • Truncation: Adds "..." suffix to indicate truncation
  • Logging: Debug logs show when truncation occurs

2. Sign & Send Transactions

This is the core method for executing transactions across all supported networks

The sign_and_send() method accepts any pre-built transaction for the target network. You have complete control over how you build these transactions.

Ethereum (any EVM chain)

# Native ETH transfer
await sdk.sign_and_send({
    "network": "ethereum:1",  # Chain ID in network string
    "request": {
        "to_address": "0x742d35cc6634C0532925a3b8D65e95f32B6b5582",
        "data": "0x",
        "value": "1000000000000000000"  # 1 ETH in wei
    },
    "message": "Sending 1 ETH"
})

# Contract interaction (e.g., ERC-20 transfer)
await sdk.sign_and_send({
    "network": "ethereum:42161",  # Arbitrum
    "request": {
        "to_address": "0xTokenContract...",
        "data": "0xa9059cbb...",  # encoded transfer(address,uint256)
        "value": "0"
    },
    "message": "ERC-20 transfer"
})

# You can build the transaction data using web3.py:
from web3 import Web3
w3 = Web3()
contract = w3.eth.contract(abi=ERC20_ABI)
data = contract.encodeABI(fn_name="transfer", args=[recipient, amount])

Solana

# Any Solana transaction (transfers, swaps, etc.)
await sdk.sign_and_send({
    "network": "solana",
    "request": {
        "hex_transaction": "010001030a0b..."  # serialized VersionedTransaction
    },
    "message": "Solana transaction"
})

# Build transactions using solana-py or solders:
from solders.transaction import VersionedTransaction
from solders.message import Message
# ... build your transaction
tx = VersionedTransaction(message, [NullSigner(payer)])
hex_transaction = bytes(tx).hex()

# Or use our optional utilities for simple cases:
from agent_sdk.utils.solana import create_native_sol_transfer_transaction
hex_tx = await create_native_sol_transfer_transaction(...)

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

circuit_agent_sdk-1.0.1.tar.gz (126.6 kB view details)

Uploaded Source

Built Distribution

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

circuit_agent_sdk-1.0.1-py3-none-any.whl (25.7 kB view details)

Uploaded Python 3

File details

Details for the file circuit_agent_sdk-1.0.1.tar.gz.

File metadata

  • Download URL: circuit_agent_sdk-1.0.1.tar.gz
  • Upload date:
  • Size: 126.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.11

File hashes

Hashes for circuit_agent_sdk-1.0.1.tar.gz
Algorithm Hash digest
SHA256 c04ac0d8b04ed6d2c00296c80be664e1c0efdc23e83a8b36c29eb649a1760ff3
MD5 e957790f7713df61a4804a830bb9752d
BLAKE2b-256 f1252e18f5be824623514208de58d9e96fe954d867a4135592deaf7ad0a4fbad

See more details on using hashes here.

File details

Details for the file circuit_agent_sdk-1.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for circuit_agent_sdk-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 45a7f8bcb3549eb2eee2b778f93aa9f068b54c52e24439ad7e1145d2068ca436
MD5 292f873af26ce9435d944079a94f64e1
BLAKE2b-256 234fcdf65049762f889cf88b25105ae03c57eeb12576a9a63c3a1728e2a03bf5

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