Reference

Python SDK

Complete reference for the pacerelle package — client options, methods, message types and Agent Connect helpers.

Terminal
pip install --pre pacerelle

Requires CPython 3.12. Wheels bundle the native encryption library for Windows x64, Linux x64, Linux ARM64 and macOS ARM64.

from pacerelle import AgentGatewayClient

The SDK is in alpha. APIs may still change before 1.0.

AgentGatewayClient

client = AgentGatewayClient(
    agent_id=os.environ["PACERELLE_AGENT_ID"],
    token=os.environ["PACERELLE_AGENT_TOKEN"],
    e2ee=True,
)

All arguments are keyword-only.

agent_idstrrequired
The agent ID from the app.
tokenstrrequired
The agent token, or an Agent Connect runtime token.
e2eebool
Enable end-to-end encryption. Defaults to Falsealways set True outside local debugging.
store_rootstr | PathLike
Directory for the encryption state. Defaults to ~/.myagents; the state lives in <store_root>/<agent_id>/signal.db.
base_urlstr
API URL. Defaults to https://api.pacerelle.com.
ws_urlstr
WebSocket URL. Derived from base_url by default.

With e2ee=True, the client opens its SQLite state store immediately and restores the agent's keys. Use one process per store.

Connection

MethodDescription
await connect()Publishes the agent's public keys if needed, opens the WebSocket and processes messages until the connection ends. Doesn't reconnect by itself — see reconnecting.
close()Closes the state store. Call it before creating a new client.
publish_prekey_bundle()Publishes the agent's public keys. Called by connect() when needed.
get_verification_code()Returns the verification code, after the keys were published. See Verify your agent.

Receiving

on_message(handler)

async def handle(message: AgentMessage, agent: AgentGatewayClient) -> None: ...

client.on_message(handle)

The handler can be async or a regular function. Messages are processed one at a time, in order; a message is acknowledged once the handler returns without raising.

on_identity_changed(handler)

Called with a user ID when that user's identity key changed (for example after reinstalling the app). Informational: the SDK keeps working and never replaces the agent's own identity.

Sending

reply

await agent.reply(message, "Done.", attachments=None)

Answers a message in its conversation — or its group — on the device that sent it, linked to the original message. The recommended way to reply.

send_message

await agent.send_message(
    conversation_id=message.conversation_id,
    to=message.from_id,
    text="Done.",
    reply_to_message_id=message.id,   # optional, recommended
    attachments=None,                 # optional list[AgentAttachment]
)

Raises RuntimeError if the agent isn't connected. Pass to=f"group:{conversation_id}" to write to a whole group.

Files

MethodDescription
await send_file(conversation_id, to, name, data, mime=..., text="", reply_to_message_id=None)Encrypts, uploads and sends a file. Returns the AgentAttachment.
await send_media(conversation_id, to, name, data, mime, text="", width=None, height=None, duration_ms=None)Same, with media hints.
upload_file(name, data, mime=...)Encrypts and uploads without sending.
await download_attachment(attachment)Downloads a received file and decrypts it locally. Returns bytes. See Files and media.

Widgets

Each method takes conversation_id, to, title, and optionally widget_id, body and expires_at (ISO 8601). Each returns the widget ID. See Interactive widgets.

MethodSpecific arguments
send_confirm_widgetdanger, labels={"yes": …, "no": …}, response_mode
send_choice_widgetoptions=[{"id", "label"}], multi=True, response_mode
send_permission_widgetscopes=["once", "session"]
send_form_widgetfields=[{"name", "label", "type", "required", …}], submitLabel
send_datetime_widgetmode="date" | "time" | "datetime", min, max
send_file_picker_widgetmultiple, accept, max_files
send_progress_widgetvalue, max, cancellable
send_widget_updateref, spec, expires_at — updates a widget already sent

response_mode is "individual" or "collective" — see collective votes.

Types

AgentMessage

A frozen dataclass.

FieldTypeDescription
idstrMessage ID.
conversation_idstrConversation ID.
from_idstrSender ID — use it as to when replying.
from_device_idstr | NoneSender's device.
textstrMessage text.
reply_to_message_idstr | NoneThe message this one replies to.
attachmentslist[AgentAttachment] | NoneAttached files.
widget_responseAgentWidgetResponse | NoneAnswer to a widget: ref, value, cancelled, id.
widget_updateAgentWidgetUpdate | NoneUpdate to a widget.
encryptedboolWhether the message was end-to-end encrypted.

AgentAttachment

id, name, mime, size, blob_id, optional width, height, duration_ms, and the per-file key key_b64 / iv_b64.

Permissions

from pacerelle.permissions import PermissionPolicy, PermissionSession

Same contract as the JavaScript policy: create_request, receive_response, run_authorized, create_widget_update, revoke, end_session, list_grants. See Permissions.

Agent Connect

Synchronous server-side helpers for Agent Connect. All accept an optional base_url.

FunctionReturns
begin_agent_connect(connect_key, client_id, redirect_uri, agent_name, agent_description="", state=None)AgentConnectStartauthorization_url, state, code_verifier, request_id, expires_at, expires_in
exchange_agent_connect_code(code, code_verifier, client_id, redirect_uri)AgentConnectInstallationTokeninstallation_token, agent_id, owner_id, conversation_id, scope
request_agent_runtime_token(installation_token)AgentConnectRuntimeTokenagent_token, agent_id, owner_id, conversation_id, expires_in