Agents

AIChatClient

View as MarkdownOpen in Claude

AIChatClient sends messages to an AI agent and returns its replies. The agent is the same one a phone call would reach, and each call to chat() runs one full turn.

It is async-first. A turn waits on a full model round trip, measured in seconds, and the typical consumers run on an asyncio event loop where a blocking HTTP call would stall every other conversation. Use it as an async context manager, or call close() yourself.

$pip install signalwire-sdk

This class holds your API token, so it belongs on a server you control. To reach an agent from a browser, use ChatGateway instead.

Parameters

project
str | None

Your project ID. Falls back to SIGNALWIRE_PROJECT_ID. Raises ValueError when neither is set.

token
str | None

An API token with the chat scope. Falls back to SIGNALWIRE_API_TOKEN.

space
str | None

Your Space name, used to build the service URL. Falls back to SIGNALWIRE_SPACE.

url
str | None

The service URL, used verbatim. Overrides space. Raises ValueError when neither is available.

session
aiohttp.ClientSession | None

An existing session to send requests on. When omitted, the client creates and owns one, and close() closes it. Pass your own to control connection pooling or timeouts.

The client does not add Basic authentication or its User-Agent to a session you supply. Configure those headers on the session before passing session=, or let the client create the session.

A configured environment needs no arguments at all. Identity travels in HTTP Basic auth, never in the request body.

Return types

ConversationInfo
dataclass

Returned by create_conversation(). Carries id, status, and initial_message.

ChatResponse
dataclass

Returned by chat(). Carries text, conversation_id, and user_event.

ChatLog
dataclass

Returned by log(). Carries messages and call_timeline.

Exceptions

All inherit from AIChatError, which carries code and message. Codes without a specific class raise AIChatError itself. Documented codes are listed under AI chat errors.

AuthenticationError
AIChatError

A JSON-RPC -32009 response. A public-endpoint HTTP 401 currently raises AIChatError instead.

ConversationNotFoundError
AIChatError

No conversation with that id exists in your project.

RateLimitError
AIChatError

The service returned a JSON-RPC rate-limit error.

ChatInProgressError
AIChatError

The service returned a JSON-RPC error indicating that a chat operation is already in progress.

SummaryError
AIChatError

Summary generation failed. code is None, because this failure rides the success envelope rather than arriving as a JSON-RPC error.

The client maps JSON-RPC error codes to these classes. Platform errors do not always use a JSON-RPC envelope, so an HTTP failure can raise AIChatError directly or, for some JSON response shapes, produce an empty result. Check the API error when handling failed calls.

Timeouts

The default session has no client-side total cap, a 10-second connect timeout, and a 60-second sock_read timeout. The public endpoint separately limits an individual request to 30 seconds; a slower turn returns the same 502 response as an unavailable service.

Methods

Example

1import asyncio
2
3from signalwire.ai_chat import AIChatClient
4
5CONFIG_URL = "https://bayview-taxi.example.com/swml"
6
7
8async def main():
9 async with AIChatClient(space="your-space") as client:
10 info = await client.create_conversation("chat-8f21", config_url=CONFIG_URL)
11 print("Ada:", info.initial_message)
12
13 reply = await client.chat(
14 "chat-8f21", "How much is a van from 123 Gough Street to the airport?"
15 )
16 print("Ada:", reply.text)
17
18 await client.end("chat-8f21")
19
20
21asyncio.run(main())

The AI chat endpoint documents the wire protocol underneath this class.