Skip to main content

The Python SDK for the Agent Computer Interface (ACI) by Aipotheosis Labs

Project description

ACI Python SDK

PyPI version

The official Python SDK for the ACI (Agent-Computer Interface) by Aipolabs. Currently in beta, breaking changes are expected.

The ACI Python SDK provides convenient access to the ACI REST API from any Python 3.10+ application.

Documentation

The detailed documentation is available here.

Installation

pip install aci-sdk

or with uv:

uv add aci-sdk

Usage

ACI platform is built with agent-first principles. Although you can call each of the APIs below any way you prefer in your application, we strongly recommend trying the Agent-centric features and taking a look at the agent examples to get the most out of the platform and to enable the full potential and vision of future agentic applications.

Client

from aci import ACI

client = ACI(
    # it reads from environment variable by default so you can omit it if you set it in your environment
    api_key=os.environ.get("ACI_API_KEY")
)

Apps

Types

from aci.types.apps import AppBasic, AppDetails

Methods

# search for apps, returns list of basic app data, sorted by relevance to the intent
# all parameters are optional
apps: list[AppBasic] = client.apps.search(
    intent="I want to search the web",
    allowed_apps_only=False, # If true, only return apps that are allowed by the agent/accessor, identified by the api key.
    include_functions=False, # If true, include functions (name and description) in the search results.
    categories=["search"],
    limit=10,
    offset=0
)
# get detailed information about an app, including functions supported by the app
app_details: AppDetails = client.apps.get(app_name="BRAVE_SEARCH")

App Configurations

Types

from aci.types.app_configurations import AppConfiguration
from aci.types.enums import SecurityScheme

Methods

# Create a new app configuration
configuration = client.app_configurations.create(
    app_name="GMAIL",
    security_scheme=SecurityScheme.OAUTH2
)
# List app configurations
# All parameters are optional
configurations: list[AppConfiguration] = client.app_configurations.list(
    app_names=["GMAIL", "BRAVE_SEARCH"],  # Filter by app names
    limit=10,  # Maximum number of results
    offset=0   # Pagination offset
)
# Get app configuration by app name
configuration: AppConfiguration = client.app_configurations.get(app_name="GMAIL")
# Delete an app configuration
client.app_configurations.delete(app_name="GMAIL")

Linked Accounts

Types

from aci.types.linked_accounts import LinkedAccount
from aci.types.enums import SecurityScheme

Methods

# Link an account
# Returns created LinkedAccount for API_KEY and NO_AUTH security schemes
# Returns authorization URL string for OAUTH2 security scheme (you need to finish the flow in browser to create the account)
result = client.linked_accounts.link(
    app_name="BRAVE_SEARCH",                  # Name of the app to link to
    linked_account_owner_id="user123",        # ID to identify the owner of this linked account
    security_scheme=SecurityScheme.API_KEY,   # Type of authentication
    api_key="your-api-key"                    # Required for API_KEY security scheme
)

# OAuth2 example (returns auth URL for user to complete OAuth flow in browser)
oauth_url = client.linked_accounts.link(
    app_name="GMAIL",
    linked_account_owner_id="user123",
    security_scheme=SecurityScheme.OAUTH2,
    # Optional parameter to redirect to a custom URL after the OAuth2 flow (default to https://platform.aci.dev)
    after_oauth2_link_redirect_url="https://<your website for your end users>"
)

# No-auth example
account = client.linked_accounts.link(
    app_name="AGENT_SECRETS_MANAGER",
    linked_account_owner_id="user123",
    security_scheme=SecurityScheme.NO_AUTH
)
# List linked accounts
# All parameters are optional
accounts: list[LinkedAccount] = client.linked_accounts.list(
    app_name="BRAVE_SEARCH",                  # Filter by app name
    linked_account_owner_id="user123"         # Filter by owner ID
)
# Get a specific linked account by ID (note: linked_account_id is different from the linked_account_owner_id)
account: LinkedAccount = client.linked_accounts.get(linked_account_id=account_id)
# Enable a linked account (note: linked_account_id is different from the linked_account_owner_id)
account: LinkedAccount = client.linked_accounts.enable(linked_account_id=account_id)
# Disable a linked account (note: linked_account_id is different from the linked_account_owner_id)
account: LinkedAccount = client.linked_accounts.disable(linked_account_id=account_id)
# Delete a linked account (note: linked_account_id is different from the linked_account_owner_id)
client.linked_accounts.delete(linked_account_id=account_id)

Functions

Types

from aci.types.functions import FunctionExecutionResult
from aci.types.enums import FunctionDefinitionFormat

Methods

# search for functions, returns list of basic function data, sorted by relevance to the intent
# all parameters are optional
functions: list[dict] = client.functions.search(
    app_names=["BRAVE_SEARCH", "TAVILY"],
    intent="I want to search the web",
    allowed_apps_only=False, # If true, only returns functions of apps that are allowed by the agent/accessor, identified by the api key.
    format=FunctionDefinitionFormat.OPENAI, # The format of the functions, can be OPENAI, ANTHROPIC, BASIC (name and description only)
    limit=10,
    offset=0
)
# get function definition of a specific function, this is the schema you can feed into LLM
# the actual format is defined by the format parameter: OPENAI, ANTHROPIC, BASIC (name and description only)
function_definition: dict = client.functions.get_definition(
    function_name="BRAVE_SEARCH__WEB_SEARCH",
    format=FunctionDefinitionFormat.OPENAI
)
# execute a function with the provided parameters
result: FunctionExecutionResult = client.functions.execute(
    function_name="BRAVE_SEARCH__WEB_SEARCH",
    function_parameters={"query": {"q": "what is the weather in barcelona"}},
    linked_account_owner_id="john_doe"
)

if result.success:
    print(result.data)
else:
    print(result.error)

Utility functions

to_json_schema

Convert a local python function to a LLM compatible tool schema, so you can use custom functions (tools) along with ACI.dev functions (tools).

from aci import to_json_schema

# dummy function to test the schema conversion
def custom_function(
    required_int: int,
    optional_str_with_default: str = "default string",
) -> None:
    """This is a test function.

    Args:
        required_int: This is required_int.
        optional_str_with_default: This is optional_str_with_default.
    """
    pass

# for openai chat completions api
custom_function_openai_chat_completions = to_json_schema(custom_function, FunctionDefinitionFormat.OPENAI)
"""result:
{
    "type": "function",
    "function": {
        "name": "custom_function",
        "description": "This is a test function.",
        "parameters": {
            "properties": {
                "required_int": {
                    "description": "This is required_int.",
                    "title": "Required Int",
                    "type": "integer"
                },
                "optional_str_with_default": {
                    "default": "default string",
                    "description": "This is optional_str_with_default.",
                    "title": "Optional Str With Default",
                    "type": "string"
                }
            },
            "required": ["required_int"],
            "title": "custom_function_args",
            "type": "object",
            "additionalProperties": False
        }
    }
}
"""

# alternative format: for openai responses api
custom_function_openai_responses = to_json_schema(custom_function, FunctionDefinitionFormat.OPENAI_RESPONSES)

# alternative format: for anthropic api
custom_function_anthropic = to_json_schema(custom_function, FunctionDefinitionFormat.ANTHROPIC)

# use the tool in a openai chat completion api
response = openai.chat.completions.create(
    model="gpt-4o",
    messages=[
        {
            "role": "system",
            "content": "You are a helpful assistant with access to a variety of tools.",
        },
    ],
    tools=[custom_function_openai_chat_completions]
)

Agent-centric features

The SDK provides a suite of features and helper functions to make it easier and more seamless to use functions in LLM powered agentic applications. This is our vision and the recommended way of trying out the SDK.

Meta Functions and Unified Function Calling Handler

  • A set of meta functions that can be used with LLMs as tools directly. Essentially, they are just the json schema version of some of the backend APIs of ACI.dev. They are provided so that your LLM/Agent can utlize some of the features of ACI.dev directly via function (tool) calling.

  • A unified handler for function (tool) calls, which handles both the direct function calls (e.g., BRAVE_SEARCH__WEB_SEARCH) and the meta functions calls (e.g., ACISearchFunctions, ACIExecuteFunction).

from aci.meta_functions import ACISearchFunctions, ACIExecuteFunction
from aci.types.enums import FunctionDefinitionFormat

# meta functions
tools = [
    ACISearchFunctions.to_json_schema(FunctionDefinitionFormat.OPENAI),
    ACIExecuteFunction.to_json_schema(FunctionDefinitionFormat.OPENAI),
]

# use the meta functions (tools) in a openai chat completion api
response = openai.chat.completions.create(
    model="gpt-4o",
    messages=[
        {
            "role": "system",
            "content": "Can you help star aipotheosis-labs/aci github repo?",
        },
    ],
    tools=tools
)
# unified function calling handler
tool_call = response.choices[0].message.tool_calls[0]

result = client.handle_function_call(
    tool_call.function.name,
    json.loads(tool_call.function.arguments),
    linked_account_owner_id="john_doe",
    allowed_apps_only=True,
    format=FunctionDefinitionFormat.OPENAI
)

Please see agent examples for more advanced and complete examples.

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

aci_sdk-1.0.0b2.tar.gz (63.6 kB view details)

Uploaded Source

Built Distribution

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

aci_sdk-1.0.0b2-py3-none-any.whl (31.9 kB view details)

Uploaded Python 3

File details

Details for the file aci_sdk-1.0.0b2.tar.gz.

File metadata

  • Download URL: aci_sdk-1.0.0b2.tar.gz
  • Upload date:
  • Size: 63.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.6

File hashes

Hashes for aci_sdk-1.0.0b2.tar.gz
Algorithm Hash digest
SHA256 b5f6b97c65adbacdf835bbba9d691dd55ad4aeae941eae68d5fb05ea01da802a
MD5 585fbbba635b86438656cd493fb77bc4
BLAKE2b-256 6857bd2b54e6ee84db1606e9959cabdde5fc6dace3e34dd360a62663d353e868

See more details on using hashes here.

File details

Details for the file aci_sdk-1.0.0b2-py3-none-any.whl.

File metadata

  • Download URL: aci_sdk-1.0.0b2-py3-none-any.whl
  • Upload date:
  • Size: 31.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.6.6

File hashes

Hashes for aci_sdk-1.0.0b2-py3-none-any.whl
Algorithm Hash digest
SHA256 5ff09d074e1e146b536fe19334ea7ab03e62c75657ba0628bfb8778d376a7140
MD5 f35c6be1f7787a6ce0d7cea96130cbd2
BLAKE2b-256 5e57943ce077b823bce9a9d8f223cde70c12d9fbe923392f62d89cabea7cd7e1

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