From 1724a7cf90feb4631e8568c8c71bca5e19a37ebc Mon Sep 17 00:00:00 2001 From: jahuang Date: Mon, 18 May 2026 11:00:00 -0700 Subject: [PATCH 1/7] Add MkDocs documentation setup - Add MkDocs configuration with Material theme - Add documentation structure (getting-started, guides, examples, api) - Add GitHub Actions workflow for automatic deployment to gh-pages - Configure workflow to trigger on test-docs and main branches - Add .nojekyll file to site output for GitHub Pages compatibility Documentation will be published to: https://twilio.github.io/twilio-agent-connect-python/ Co-Authored-By: Claude Sonnet 4.5 --- .github/workflows/docs.yml | 40 ++++ .gitignore | 2 + docs/README.md | 77 ++++++++ docs/api/adapters.md | 9 + docs/api/channels.md | 11 ++ docs/api/core.md | 105 +++++++++++ docs/api/models.md | 11 ++ docs/api/server.md | 9 + docs/contributing.md | 1 + docs/examples/aws.md | 9 + docs/examples/index.md | 152 +++++++++++++++ docs/examples/openai.md | 10 + docs/getting-started/index.md | 33 ++++ docs/getting-started/installation.md | 74 ++++++++ docs/getting-started/quickstart.md | 242 ++++++++++++++++++++++++ docs/getting-started/twilio-setup.md | 132 +++++++++++++ docs/guides/architecture.md | 192 +++++++++++++++++++ docs/guides/channels.md | 269 +++++++++++++++++++++++++++ docs/guides/memory.md | 10 + docs/guides/openai-adapter.md | 10 + docs/guides/server.md | 10 + docs/index.md | 135 ++++++++++++++ mkdocs.yml | 104 +++++++++++ 23 files changed, 1647 insertions(+) create mode 100644 .github/workflows/docs.yml create mode 100644 docs/README.md create mode 100644 docs/api/adapters.md create mode 100644 docs/api/channels.md create mode 100644 docs/api/core.md create mode 100644 docs/api/models.md create mode 100644 docs/api/server.md create mode 100644 docs/contributing.md create mode 100644 docs/examples/aws.md create mode 100644 docs/examples/index.md create mode 100644 docs/examples/openai.md create mode 100644 docs/getting-started/index.md create mode 100644 docs/getting-started/installation.md create mode 100644 docs/getting-started/quickstart.md create mode 100644 docs/getting-started/twilio-setup.md create mode 100644 docs/guides/architecture.md create mode 100644 docs/guides/channels.md create mode 100644 docs/guides/memory.md create mode 100644 docs/guides/openai-adapter.md create mode 100644 docs/guides/server.md create mode 100644 docs/index.md create mode 100644 mkdocs.yml diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..3f2f6d1 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,40 @@ +name: Deploy Docs + +on: + push: + branches: + - main + - test-docs # Add your test branch here + workflow_dispatch: + +permissions: + contents: write + +jobs: + deploy: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 # Fetch all history for proper git info + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + pip install mkdocs-material mkdocstrings[python] pymdown-extensions + + - name: Build docs + run: | + mkdocs build + touch site/.nojekyll + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v4 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./site + cname: false # Remove if you want a custom domain diff --git a/.gitignore b/.gitignore index 1a7518f..55044f3 100644 --- a/.gitignore +++ b/.gitignore @@ -165,3 +165,5 @@ getting_started/examples/partners/.strands_sessions/ # Local Makefile overrides Makefile.local +/site/ +*.pyc diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 0000000..5864b2f --- /dev/null +++ b/docs/README.md @@ -0,0 +1,77 @@ +# TAC Documentation + +This directory contains the source for the TAC documentation site. + +## Local Development + +### Prerequisites + +Install dependencies: + +```bash +pip install -r docs-requirements.txt +``` + +Or use the project's uv environment: + +```bash +uv pip install mkdocs-material 'mkdocstrings[python]' pymdown-extensions +``` + +### Build and Serve + +Build the docs: + +```bash +mkdocs build +``` + +Serve locally with hot reload: + +```bash +mkdocs serve +``` + +Visit `http://127.0.0.1:8000` to view the docs. + +### Project Structure + +``` +docs/ +├── index.md # Homepage +├── getting-started/ # Installation and setup guides +├── guides/ # In-depth guides +├── examples/ # Code examples +├── api/ # API reference +└── contributing.md # Contributing guide +``` + +### Adding New Pages + +1. Create a new `.md` file in the appropriate directory +2. Add it to `nav` in `mkdocs.yml` +3. Build and verify + +## Deployment + +### GitHub Actions (Automated) + +Docs are automatically deployed to GitHub Pages when changes are pushed to `main` via the `.github/workflows/docs.yml` workflow. + +You can also trigger manually: +1. Go to: https://github.com/twilio/twilio-agent-connect-python/actions/workflows/docs.yml +2. Click "Run workflow" → Select `main` branch → "Run workflow" + +### Enable GitHub Pages (One-time Setup) + +1. Go to: https://github.com/twilio/twilio-agent-connect-python/settings/pages +2. **Source**: Deploy from a branch +3. **Branch**: `gh-pages` → `/ (root)` +4. Click **Save** +5. Wait 1-2 minutes for deployment + +**Live URL**: https://twilio.github.io/twilio-agent-connect-python/ + +## Contributing + +See [CONTRIBUTING.md](../CONTRIBUTING.md) for contribution guidelines. diff --git a/docs/api/adapters.md b/docs/api/adapters.md new file mode 100644 index 0000000..321be2d --- /dev/null +++ b/docs/api/adapters.md @@ -0,0 +1,9 @@ +# Adapters API Reference + +(Coming soon) + +This page will document: + +- OpenAI adapter +- with_tac_memory function +- Memory injection strategies diff --git a/docs/api/channels.md b/docs/api/channels.md new file mode 100644 index 0000000..d19e7b9 --- /dev/null +++ b/docs/api/channels.md @@ -0,0 +1,11 @@ +# Channels API Reference + +(Coming soon) + +This page will document: + +- VoiceChannel +- SMSChannel +- RCSChannel +- WhatsAppChannel +- ChatChannel diff --git a/docs/api/core.md b/docs/api/core.md new file mode 100644 index 0000000..52e1762 --- /dev/null +++ b/docs/api/core.md @@ -0,0 +1,105 @@ +# Core API Reference + +This page documents the core TAC classes and functions. + +## TAC + +The main orchestrator class that coordinates all TAC components. + +```python +from tac import TAC, TACConfig + +tac = TAC(config=TACConfig.from_env()) +``` + +### Methods + +#### `__init__(config: TACConfig)` + +Initialize a TAC instance with configuration. + +#### `on_message_ready(callback)` + +Register callback for when a message is ready for processing. + +```python +async def handle_message(user_message: str, context, memory_response): + return "Response" + +tac.on_message_ready(handle_message) +``` + +#### `on_conversation_ended(callback)` + +Register callback for when a conversation ends. + +```python +async def handle_ended(context): + print(f"Conversation {context.conversation_id} ended") + +tac.on_conversation_ended(handle_ended) +``` + +#### `retrieve_memory(profile_id, conversation_id, query=None)` + +Manually retrieve memory for a user. + +#### `is_orchestrator_enabled()` + +Check if Conversation Orchestrator is configured. + +## TACConfig + +Configuration for TAC instances. + +```python +from tac import TACConfig + +# From environment +config = TACConfig.from_env() + +# Manual +config = TACConfig( + api_key="SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + api_token="your_api_secret_here", + account_sid="ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", + conversation_configuration_id="conv_configuration_xxxxx" +) +``` + +### Fields + +- `api_key: str` - Twilio API Key SID +- `api_token: str` - Twilio API Token (Secret) +- `account_sid: str` - Twilio Account SID +- `conversation_configuration_id: str | None` - Conversation Configuration SID (optional for ConversationRelay-only mode) + +## Context Models + +### TACContext + +Context information passed to callbacks containing conversation metadata, participant info, and profile data. + +### TACMemoryResponse + +Memory retrieval response containing user memories and profile information. + +## API Clients + +API clients for interacting with Twilio services. These are used internally by TAC but can also be used directly. + +### ConversationClient + +Client for Conversation Orchestrator API. + +### MemoryClient + +Client for Conversation Memory API. + +### KnowledgeClient + +Client for Knowledge Base API. + +--- + +**Note**: Full API reference with type signatures coming soon. For now, see the [source code](https://github.com/twilio/twilio-agent-connect-python/tree/main/src/tac) for detailed implementation. diff --git a/docs/api/models.md b/docs/api/models.md new file mode 100644 index 0000000..09b5219 --- /dev/null +++ b/docs/api/models.md @@ -0,0 +1,11 @@ +# Models API Reference + +(Coming soon) + +This page will document all Pydantic models: + +- Memory models +- Conversation models +- Session models +- Voice models +- Knowledge models diff --git a/docs/api/server.md b/docs/api/server.md new file mode 100644 index 0000000..4084740 --- /dev/null +++ b/docs/api/server.md @@ -0,0 +1,9 @@ +# Server API Reference + +(Coming soon) + +This page will document: + +- TACFastAPIServer +- Server configuration +- Custom endpoints diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 0000000..ea38c9b --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1 @@ +--8<-- "CONTRIBUTING.md" diff --git a/docs/examples/aws.md b/docs/examples/aws.md new file mode 100644 index 0000000..680e927 --- /dev/null +++ b/docs/examples/aws.md @@ -0,0 +1,9 @@ +# AWS Examples + +(Coming soon) + +Examples will cover: + +- AWS Bedrock Agent +- AWS Bedrock AgentCore +- AWS Strands diff --git a/docs/examples/index.md b/docs/examples/index.md new file mode 100644 index 0000000..6f5fae8 --- /dev/null +++ b/docs/examples/index.md @@ -0,0 +1,152 @@ +# Examples + +TAC comes with comprehensive examples demonstrating various integration patterns and use cases. + +## Example Repository Structure + +All examples are located in the [`getting_started/examples`](https://github.com/twilio/twilio-agent-connect-python/tree/main/getting_started/examples) directory: + +``` +getting_started/examples/ +├── partners/ # Partner SDK integrations +│ ├── openai_*.py # OpenAI examples +│ ├── bedrock_*.py # AWS Bedrock examples +│ └── strands_*.py # AWS Strands examples +└── features/ # Feature-specific examples + ├── chat/ # Chat channel + ├── dashboard/ # Monitoring dashboard + └── relay_only.py # ConversationRelay-only mode +``` + +## Partner Integrations + +### OpenAI + +- [OpenAI Chat Completions](openai.md#chat-completions-api) - Using the Chat Completions API +- [OpenAI Responses API](openai.md#responses-api) - Using the new Responses API +- [OpenAI Agents SDK](openai.md#agents-sdk) - Integrating with OpenAI Agents + +### AWS + +- [AWS Bedrock Agent](aws.md#bedrock-agent) - AWS Bedrock Agent integration +- [AWS Bedrock AgentCore](aws.md#bedrock-agentcore) - AWS Bedrock AgentCore integration +- [AWS Strands](aws.md#strands) - AWS Strands agent integration + +## Feature Examples + +### ConversationRelay-Only Mode + +Start with just voice (no Orchestrator or Memory): + +```python +from tac import TAC, TACConfig +from tac.channels.voice import VoiceChannel + +config = TACConfig( + api_key=os.getenv("TWILIO_API_KEY"), + api_token=os.getenv("TWILIO_API_TOKEN"), + # No conversation_configuration_id +) + +tac = TAC(config=config) +voice_channel = VoiceChannel(tac) + +# Your voice handling logic +``` + +[View full example →](https://github.com/twilio/twilio-agent-connect-python/blob/main/getting_started/examples/features/relay_only.py) + +### Multi-Channel Support + +Handle Voice, SMS, WhatsApp, and RCS simultaneously: + +```python +from tac.channels.voice import VoiceChannel +from tac.channels.sms import SMSChannel +from tac.channels.whatsapp import WhatsAppChannel +from tac.channels.rcs import RCSChannel +from tac.server import TACFastAPIServer + +TACFastAPIServer( + tac=tac, + voice_channel=VoiceChannel(tac), + messaging_channels=[ + SMSChannel(tac), + WhatsAppChannel(tac), + RCSChannel(tac) + ] +).start() +``` + +### Memory Modes + +```python +# Always fetch memory with semantic search on every message +voice_channel = VoiceChannel(tac, memory_mode="always") + +# Fetch memory once at conversation start +sms_channel = SMSChannel(tac, memory_mode="once") + +# Never fetch memory automatically +whatsapp_channel = WhatsAppChannel(tac, memory_mode="never") +``` + +### Custom Tools + +```python +from tac.tools import function_tool + +@function_tool +async def check_weather(location: str) -> str: + """Check the weather for a location.""" + # Your weather API logic + return f"The weather in {location} is sunny" + +@function_tool +async def book_appointment(date: str, time: str) -> str: + """Book an appointment.""" + # Your booking logic + return f"Appointment booked for {date} at {time}" + +# Use with OpenAI +tools = [ + check_weather.to_openai_tool(), + book_appointment.to_openai_tool() +] + +response = await client.responses.create( + model="gpt-5.4-mini", + instructions=INSTRUCTIONS, + input=messages, + tools=tools +) +``` + +## Running Examples + +Clone the repository and install dependencies: + +```bash +git clone https://github.com/twilio/twilio-agent-connect-python.git +cd twilio-agent-connect-python +make sync +``` + +Configure your environment: + +```bash +cp .env.example .env +# Edit .env with your credentials +``` + +Run an example: + +```bash +uv run getting_started/examples/partners/openai_chat_completions.py +``` + +## Next Steps + +- [OpenAI Examples](openai.md) - Detailed OpenAI integration guides +- [AWS Examples](aws.md) - AWS Bedrock and Strands examples +- [API Reference](../api/core.md) - Complete API documentation diff --git a/docs/examples/openai.md b/docs/examples/openai.md new file mode 100644 index 0000000..d668349 --- /dev/null +++ b/docs/examples/openai.md @@ -0,0 +1,10 @@ +# OpenAI Examples + +(Coming soon) + +Examples will cover: + +- Chat Completions API +- Responses API +- OpenAI Agents SDK +- Streaming responses diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md new file mode 100644 index 0000000..c839884 --- /dev/null +++ b/docs/getting-started/index.md @@ -0,0 +1,33 @@ +# Getting Started + +Welcome to Twilio Agent Connect! This guide will help you set up TAC and build your first AI agent. + +## Prerequisites + +- Python 3.10 or newer +- A Twilio account ([Sign up here](https://www.twilio.com/try-twilio)) +- Basic familiarity with Python async/await + +## Setup Options + +TAC offers two ways to get started: + +### Option 1: Setup Wizard (Recommended) + +Use the [Twilio Setup Wizard](twilio-setup.md) to automatically create a Memory Store and Conversation Configuration and generate your `.env` file: + +```bash +git clone https://github.com/twilio/twilio-agent-connect-python.git +cd twilio-agent-connect-python +make setup # Open http://localhost:8080 +``` + +### Option 2: Manual Setup + +You can also create a Memory Store and Conversation Configuration manually through the [Twilio Console](https://console.twilio.com). For a full walkthrough — credentials, Console navigation, and webhook configuration — see the [TAC Quickstart](https://www.twilio.com/docs/conversations/agent-connect/quickstart). + +## What's Next? + +- [Installation Guide](installation.md) - Install TAC in your project +- [Quick Start](quickstart.md) - Build your first agent +- [Twilio Setup](twilio-setup.md) - Configure Twilio services diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md new file mode 100644 index 0000000..b79b435 --- /dev/null +++ b/docs/getting-started/installation.md @@ -0,0 +1,74 @@ +# Installation + +## Requirements + +- Python 3.10 or newer +- pip or uv package manager + +## Install from PyPI + +### Basic Installation + +For basic TAC functionality (channels, memory, adapters): + +```bash +pip install twilio-agent-connect +``` + +### With Server Support + +To include the FastAPI-based `TACFastAPIServer`: + +```bash +pip install "twilio-agent-connect[server]" +``` + +This installs additional dependencies: + +- `fastapi>=0.115.0` +- `uvicorn[standard]>=0.32.0` +- `python-multipart>=0.0.20` + +## Install from Source + +For development or to try the latest features: + +```bash +git clone https://github.com/twilio/twilio-agent-connect-python.git +cd twilio-agent-connect-python +make sync # Installs via uv +``` + +## Verify Installation + +```python +import tac +print(f"TAC version: {tac.__version__}") +``` + +## Additional Dependencies + +Depending on your use case, you may need additional packages: + +### For OpenAI Integration + +```bash +pip install openai python-dotenv +``` + +### For AWS Integration + +```bash +pip install boto3 boto3-stubs[bedrock-agent-runtime,bedrock-agentcore] strands-agents +``` + +### For Development + +```bash +pip install pytest pytest-asyncio ruff mypy +``` + +## Next Steps + +- [Quick Start Guide](quickstart.md) - Build your first agent +- [Twilio Setup](twilio-setup.md) - Configure Twilio services diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md new file mode 100644 index 0000000..a78a21e --- /dev/null +++ b/docs/getting-started/quickstart.md @@ -0,0 +1,242 @@ +# Quick Start + +This guide will walk you through building your first TAC-powered AI agent in under 10 minutes. + +## Prerequisites + +Before starting, ensure you have: + +- Python 3.10+ installed +- A Twilio account with API credentials +- Completed the [Twilio Setup](twilio-setup.md) (or have Memory Store and Conversation Configuration IDs) + +## Step 1: Install TAC + +```bash +pip install "twilio-agent-connect[server]" openai python-dotenv +``` + +## Step 2: Configure Environment + +Create a `.env` file with your Twilio credentials: + +```bash +# Twilio credentials +TWILIO_API_KEY=your_api_key +TWILIO_API_TOKEN=your_api_token +TWILIO_ACCOUNT_SID=your_account_sid + +# TAC configuration +CONVERSATION_CONFIGURATION_ID=your_config_id + +# OpenAI +OPENAI_API_KEY=your_openai_key +``` + +## Step 3: Create Your Agent + +Create `app.py`: + +```python +from dotenv import load_dotenv +from openai import AsyncOpenAI +from tac import TAC, TACConfig +from tac.adapters.openai import with_tac_memory +from tac.channels.sms import SMSChannel +from tac.channels.voice import VoiceChannel +from tac.server import TACFastAPIServer + +load_dotenv() + +# Initialize TAC +tac = TAC(config=TACConfig.from_env()) +voice_channel = VoiceChannel(tac) +sms_channel = SMSChannel(tac) +openai_client = AsyncOpenAI() + +# Store conversation history per conversation +conversation_history = {} + +SYSTEM_INSTRUCTIONS = ( + "You are a helpful customer service agent. " + "Keep responses short and conversational. " + "Do not use markdown or emojis." +) + +async def handle_message_ready(user_message, context, memory_response): + """Called when a message is ready for processing.""" + conv_id = context.conversation_id + + # Initialize or retrieve conversation history + if conv_id not in conversation_history: + conversation_history[conv_id] = [] + + conversation_history[conv_id].append({ + "role": "user", + "content": user_message + }) + + # Wrap OpenAI client with TAC memory injection + client = with_tac_memory(openai_client, memory_response, context) + + # Generate response + response = await client.responses.create( + model="gpt-5.4-mini", + instructions=SYSTEM_INSTRUCTIONS, + input=conversation_history[conv_id] + ) + + llm_response = response.output_text + conversation_history[conv_id].append({ + "role": "assistant", + "content": llm_response + }) + + return llm_response + +# Register callback +tac.on_message_ready(handle_message_ready) + +# Start server +TACFastAPIServer( + tac=tac, + voice_channel=voice_channel, + messaging_channels=[sms_channel] +).start() +``` + +## Step 4: Run Your Agent + +```bash +python app.py +``` + +Your server will start on `http://localhost:8000` with these endpoints: + +- `/twiml` - Voice call entry point +- `/ws` - WebSocket for ConversationRelay +- `/webhook` - Messaging webhooks (SMS, WhatsApp, etc.) + +## Step 5: Test It Out + +### Option A: Use ngrok for Testing + +```bash +# Install ngrok +brew install ngrok # macOS +# or download from https://ngrok.com/ + +# Expose your local server +ngrok http 8000 +``` + +Configure your Twilio phone number webhooks to point to your ngrok URL: + +- Voice: `https://your-ngrok-url.ngrok.io/twiml` +- SMS: `https://your-ngrok-url.ngrok.io/webhook` + +### Option B: Deploy to Production + +See the [Server Setup Guide](../guides/server.md) for deployment options. + +## What Just Happened? + +Let's break down the code: + +1. **TAC Initialization**: Loads configuration from environment variables +2. **Channel Setup**: Creates Voice and SMS channels +3. **Callback Registration**: `on_message_ready` processes each message +4. **Memory Injection**: `with_tac_memory()` automatically adds user context to OpenAI calls +5. **Server Creation**: `TACFastAPIServer` handles all webhook routing + +## Next Steps + +### Add More Channels + +```python +from tac.channels.whatsapp import WhatsAppChannel +from tac.channels.rcs import RCSChannel + +whatsapp = WhatsAppChannel(tac) +rcs = RCSChannel(tac) + +TACFastAPIServer( + tac=tac, + voice_channel=voice_channel, + messaging_channels=[sms_channel, whatsapp, rcs] +).start() +``` + +### Enable Memory Retrieval + +Configure when to fetch user memories: + +```python +voice_channel = VoiceChannel(tac, memory_mode="always") +sms_channel = SMSChannel(tac, memory_mode="once") +``` + +Options: + +- `"never"` (default): No memory retrieval +- `"always"`: Fetch on every message with semantic search +- `"once"`: Fetch once at conversation start, cache results + +### Add Tools + +Give your agent capabilities: + +```python +from tac.tools import function_tool + +@function_tool +async def get_order_status(order_id: str) -> str: + """Check the status of an order.""" + # Your logic here + return f"Order {order_id} is in transit" + +# Use with OpenAI +tools = [get_order_status.to_openai_tool()] +``` + +### Handle Conversation End + +```python +async def handle_conversation_ended(context): + """Called when conversation ends.""" + conv_id = context.conversation_id + if conv_id in conversation_history: + del conversation_history[conv_id] + print(f"Conversation {conv_id} ended") + +tac.on_conversation_ended(handle_conversation_ended) +``` + +## Common Issues + +### "Configuration not found" + +Make sure your `.env` file contains valid IDs and your Twilio credentials are correct. + +### "Port 8000 already in use" + +Change the port: + +```python +TACFastAPIServer(...).start(host="0.0.0.0", port=8080) +``` + +### Memory not working + +Verify: + +1. Your Conversation Configuration has a Memory Store configured +2. Memory mode is set to `"always"` or `"once"` +3. Your Twilio account has Conversation Memory enabled + +## Learn More + +- [Architecture Guide](../guides/architecture.md) - Understand how TAC works +- [Channels Guide](../guides/channels.md) - Deep dive into channels +- [Memory Management](../guides/memory.md) - Memory retrieval strategies +- [Examples](../examples/index.md) - More code examples diff --git a/docs/getting-started/twilio-setup.md b/docs/getting-started/twilio-setup.md new file mode 100644 index 0000000..4614afc --- /dev/null +++ b/docs/getting-started/twilio-setup.md @@ -0,0 +1,132 @@ +# Twilio Setup + +This guide covers setting up the required Twilio resources for TAC. + +## Prerequisites + +- A Twilio account ([Sign up here](https://www.twilio.com/try-twilio)) +- Twilio API credentials (API Key and Secret) + +## Option 1: Setup Wizard (Recommended) + +The easiest way to get started is using our setup wizard: + +```bash +git clone https://github.com/twilio/twilio-agent-connect-python.git +cd twilio-agent-connect-python +make setup +``` + +This opens a web interface at `http://localhost:8080` that will: + +1. Create a Memory Store +2. Create a Conversation Configuration +3. Link them together +4. Generate your `.env` file + +## Option 2: Manual Setup + +### Step 1: Create API Credentials + +1. Go to [Twilio Console - API Keys](https://console.twilio.com/us1/account/keys-credentials/api-keys) +2. Click "Create API Key" +3. Name it (e.g., "TAC Development") +4. Save the SID (API Key) and Secret (API Token) securely + +### Step 2: Create a Memory Store + +1. Go to [Conversation Memory Console](https://console.twilio.com/us1/develop/conversations/memory) +2. Click "Create Memory Store" +3. Configure your store: + - **Name**: e.g., "TAC Memory Store" + - **Description**: Optional +4. Save the Memory Store SID + +### Step 3: Create a Conversation Configuration + +1. Go to [Conversation Orchestrator Console](https://console.twilio.com/us1/develop/conversations/orchestrator) +2. Click "Create Configuration" +3. Configure: + - **Name**: e.g., "TAC Configuration" + - **Memory Store**: Select the store from Step 2 + - **Other settings**: Configure as needed +4. Save the Configuration SID + +### Step 4: Configure Environment + +Create a `.env` file: + +```bash +# Twilio Account +TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxx +TWILIO_API_KEY=SKxxxxxxxxxxxxxxxxxxxxxxxxxxxx +TWILIO_API_TOKEN=your_api_token + +# TAC Configuration +CONVERSATION_CONFIGURATION_ID=OCxxxxxxxxxxxxxxxxxxxxxxxxxxxx + +# Optional: For voice +TWILIO_PHONE_NUMBER=+1234567890 + +# Optional: For OpenAI integration +OPENAI_API_KEY=sk-... +``` + +### Step 5: Set Up Phone Number Webhooks + +For Voice: + +1. Go to [Phone Numbers](https://console.twilio.com/us1/develop/phone-numbers/manage/incoming) +2. Select your number +3. Under "Voice Configuration": + - **A CALL COMES IN**: Webhook, `https://your-domain.com/twiml`, HTTP POST + +For SMS: + +1. Same phone number settings +2. Under "Messaging Configuration": + - **A MESSAGE COMES IN**: Webhook, `https://your-domain.com/webhook`, HTTP POST + +For WhatsApp: + +1. Go to [WhatsApp Senders](https://console.twilio.com/us1/develop/sms/senders/whatsapp-senders) +2. Select your sender +3. Configure webhook: `https://your-domain.com/webhook` + +## Verify Setup + +Test your configuration: + +```python +from tac import TAC, TACConfig + +config = TACConfig.from_env() +tac = TAC(config=config) + +# Check if Orchestrator is enabled +print(f"Orchestrator enabled: {tac.is_orchestrator_enabled()}") +``` + +## Troubleshooting + +### "Invalid API credentials" + +- Verify API Key and Token are correct +- Check that API Key is active in Twilio Console +- Ensure Account SID matches the account that created the API Key + +### "Configuration not found" + +- Verify `CONVERSATION_CONFIGURATION_ID` is correct +- Check that the configuration exists and is active +- Ensure your API credentials have access to the configuration + +### "Memory Store not found" + +- Verify the Memory Store is linked to your Conversation Configuration +- Check Memory Store status in Twilio Console + +## Next Steps + +- [Quick Start Guide](quickstart.md) - Build your first agent +- [Installation](installation.md) - Install TAC diff --git a/docs/guides/architecture.md b/docs/guides/architecture.md new file mode 100644 index 0000000..0253436 --- /dev/null +++ b/docs/guides/architecture.md @@ -0,0 +1,192 @@ +# Architecture + +TAC is designed as middleware that connects Twilio's communication channels with your LLM application. Understanding the architecture helps you build more effective agents. + +## Core Components + +### TAC Class + +The central orchestrator that coordinates all components: + +```python +from tac import TAC, TACConfig + +tac = TAC(config=TACConfig.from_env()) +``` + +Key responsibilities: + +- Configuration management +- Memory retrieval coordination +- Callback registration and invocation +- Profile resolution + +### Channels + +Channels handle communication protocol specifics: + +- **Voice**: ConversationRelay WebSocket handling, TwiML generation +- **SMS**: SMS webhook processing +- **RCS**: RCS webhook processing with rich media +- **WhatsApp**: WhatsApp webhook processing +- **Chat**: Multi-platform chat handling + +Each channel: + +1. Validates incoming webhooks/connections +2. Manages conversation lifecycle +3. Triggers TAC callbacks +4. Routes responses back to Twilio + +### Memory System + +TAC integrates with Twilio Conversation Memory: + +- **Automatic initialization** from Conversation Orchestrator config +- **Three retrieval modes**: + - `"never"` (default): No automatic retrieval + - `"always"`: Fetch on every message with semantic search + - `"once"`: Fetch once, cache until conversation state changes +- **Graceful fallback** to Conversation Orchestrator if Memory unavailable + +### Adapters + +Adapters inject TAC context into LLM SDKs: + +- **OpenAI Adapter**: Memory injection for Chat Completions and Responses APIs +- Automatically formats memory and profile for LLM consumption +- Supports sync/async and streaming + +## Message Flow + +```mermaid +sequenceDiagram + participant User + participant Twilio + participant Channel + participant TAC + participant Memory + participant Callback + participant LLM + + User->>Twilio: Send message/call + Twilio->>Channel: Webhook/WebSocket + Channel->>TAC: Process message + TAC->>Memory: Retrieve context (optional) + Memory-->>TAC: User memories + profile + TAC->>Callback: on_message_ready + Callback->>LLM: Generate response + LLM-->>Callback: Response text + Callback-->>TAC: Return response + TAC->>Channel: Route response + Channel->>Twilio: Send via API + Twilio->>User: Deliver message +``` + +## Conversation Lifecycle + +### Connection Phase + +1. Twilio receives user message/call +2. Channel validates and processes +3. Profile lookup (if needed) +4. Memory retrieval (based on mode) +5. Conversation stored in `_conversations` + +### Active Phase + +- Messages flow through `on_message_ready` +- Memory cache maintained (for `"once"` mode) +- State tracked per conversation + +### Cleanup Phase + +- Voice: On WebSocket disconnect +- Messaging: On INACTIVE status or conversation end +- Memory cache cleared +- Conversation removed from tracking + +## ConversationRelay-Only Mode + +TAC can run without Conversation Orchestrator or Memory: + +```python +config = TACConfig( + api_key=os.getenv("TWILIO_API_KEY"), + api_token=os.getenv("TWILIO_API_TOKEN"), + # No conversation_configuration_id +) +``` + +In this mode: + +- Only Voice channel works (messaging channels raise at construction) +- `retrieve_memory()` returns empty response +- ConversationRelay callback handles session cleanup +- Perfect for voice-first prototypes + +Check at runtime: + +```python +if tac.is_orchestrator_enabled(): + # Use memory features +else: + # Voice-only mode +``` + +## Scaling Considerations + +### Single Instance + +TAC works perfectly out of the box for single-instance deployments: + +- Conversation tracking in memory (`self._conversations`) +- Automatic cleanup on disconnect/inactivity +- No shared state needed + +### Multi-Instance (Horizontal Scaling) + +Current architecture has limitations: + +- Conversation state is instance-local +- Webhooks may route to different instances +- Can cause memory leaks (conversations not cleaned up) + +**Recommended solutions:** + +1. **Sticky sessions**: Configure load balancer to route by `conversation_id` +2. **Shared state**: Use Redis or database for `_conversations` tracking + +## Key Architecture Patterns + +### Memory Fallback Chain + +1. Try Conversation Memory first +2. Fall back to Orchestrator's `list_communications()` +3. Return empty response if both fail +4. Never block callback execution + +### Profile Resolution + +1. Check if `profile_id` in webhook +2. If missing, look up by phone/email +3. Create profile if lookup fails +4. Cache in context for callback + +### Async-First Design + +- All I/O operations use `httpx.AsyncClient` +- Callbacks are async by default +- Channels handle both sync/async gracefully + +### Error Handling Philosophy + +- API failures should not crash the agent +- Log errors, return empty/default values +- Let callbacks decide how to handle missing data + +## Next Steps + +- [Channels Guide](channels.md) - Deep dive into channel implementations +- [Memory Management](memory.md) - Memory retrieval strategies +- [Server Setup](server.md) - Deploying TAC applications diff --git a/docs/guides/channels.md b/docs/guides/channels.md new file mode 100644 index 0000000..4e330c6 --- /dev/null +++ b/docs/guides/channels.md @@ -0,0 +1,269 @@ +# Channels Guide + +Channels handle the communication protocol specifics for each Twilio platform. This guide covers how to use and configure channels effectively. + +## Available Channels + +TAC provides five built-in channels: + +| Channel | Use Case | Protocol | +|---------|----------|----------| +| **Voice** | Phone calls | ConversationRelay WebSocket + TwiML | +| **SMS** | Text messages | HTTP webhooks | +| **RCS** | Rich messaging | HTTP webhooks | +| **WhatsApp** | WhatsApp Business | HTTP webhooks | +| **Chat** | Multi-platform chat | HTTP webhooks | + +## Basic Usage + +### Single Channel + +```python +from tac import TAC, TACConfig +from tac.channels.sms import SMSChannel + +tac = TAC(config=TACConfig.from_env()) +sms_channel = SMSChannel(tac) + +async def handle_message(user_message, context, memory_response): + return "Hello from SMS!" + +tac.on_message_ready(handle_message) +``` + +### Multiple Channels + +```python +from tac.channels.voice import VoiceChannel +from tac.channels.sms import SMSChannel +from tac.channels.whatsapp import WhatsAppChannel +from tac.server import TACFastAPIServer + +tac = TAC(config=TACConfig.from_env()) + +TACFastAPIServer( + tac=tac, + voice_channel=VoiceChannel(tac), + messaging_channels=[ + SMSChannel(tac), + WhatsAppChannel(tac) + ] +).start() +``` + +## Memory Modes + +All channels support three memory retrieval modes: + +### Never (Default) + +No automatic memory retrieval: + +```python +channel = SMSChannel(tac, memory_mode="never") +``` + +Use when: + +- You don't need memory +- You'll manually call `tac.retrieve_memory()` +- Testing without Memory configured + +### Always + +Fetch memory on every message with semantic search: + +```python +channel = VoiceChannel(tac, memory_mode="always") +``` + +The user's message is used as the query for semantic search. Best for: + +- Conversations where context changes frequently +- When you need the most relevant memories per message + +### Once + +Fetch memory once at conversation start, cache until conversation ends: + +```python +channel = SMSChannel(tac, memory_mode="once") +``` + +Memory is retrieved with an empty query (returns all/recent memories) and cached. Cache is invalidated when: + +- Conversation status becomes INACTIVE +- Conversation ends +- Memory Store updates memories + +Best for: + +- Long conversations with stable context +- Reducing API calls +- Faster response times + +## Voice Channel + +Handles ConversationRelay WebSocket connections and TwiML generation. + +### Configuration + +```python +from tac.channels.voice import VoiceChannel, VoiceConfig + +voice_config = VoiceConfig( + welcome_message="Hello! How can I help you?", + voice="Polly.Joanna-Neural", + language="en-US", + dtmf_detection=True +) + +voice_channel = VoiceChannel(tac, config=voice_config, memory_mode="always") +``` + +### TwiML Generation + +Voice channel automatically generates TwiML for call handling: + +```python +# The /twiml endpoint returns: + + + + + Hello! How can I help you? + +``` + +### WebSocket Handling + +The channel manages the WebSocket lifecycle: + +1. **Connection**: Client connects to `/ws` +2. **Session start**: Receives configuration from Twilio +3. **Media streaming**: Processes audio in/out +4. **Message processing**: Triggers `on_message_ready` for transcripts +5. **Cleanup**: Handles disconnection and conversation end + +### Voice-Specific Callbacks + +```python +async def handle_call_connected(context): + print(f"Call connected: {context.conversation_id}") + +async def handle_call_ended(context): + print(f"Call ended: {context.conversation_id}") + +voice_channel.on_connected(handle_call_connected) +voice_channel.on_ended(handle_call_ended) +``` + +## Messaging Channels + +SMS, RCS, WhatsApp, and Chat channels share similar webhook-based architecture. + +### SMS Channel + +```python +from tac.channels.sms import SMSChannel + +sms_channel = SMSChannel(tac, memory_mode="once") + +async def handle_sms(user_message, context, memory_response): + # Access SMS-specific data + from_number = context.from_ + to_number = context.to + + return f"Received your SMS: {user_message}" + +tac.on_message_ready(handle_sms) +``` + +### WhatsApp Channel + +```python +from tac.channels.whatsapp import WhatsAppChannel + +whatsapp_channel = WhatsAppChannel(tac, memory_mode="always") + +async def handle_whatsapp(user_message, context, memory_response): + # WhatsApp-specific context + from_number = context.from_ # e.g., "whatsapp:+1234567890" + + return "Thanks for your WhatsApp message!" + +tac.on_message_ready(handle_whatsapp) +``` + +### RCS Channel + +Rich Communication Services with media support: + +```python +from tac.channels.rcs import RCSChannel + +rcs_channel = RCSChannel(tac, memory_mode="once") + +async def handle_rcs(user_message, context, memory_response): + # RCS supports rich media + return "RCS response with rich formatting support" + +tac.on_message_ready(handle_rcs) +``` + +## Channel Context + +Each channel provides context in the callback: + +```python +async def handle_message(user_message, context, memory_response): + # Common to all channels + conversation_id = context.conversation_id + profile_id = context.profile_id + + # Channel-specific + from_number = context.from_ + to_number = context.to + + # For voice + if hasattr(context, 'call_sid'): + call_sid = context.call_sid + + return "Response" +``` + +## Manual Response Handling + +By default, returning a string sends it as the response. For manual control, return `None`: + +```python +async def handle_message(user_message, context, memory_response): + # Process message + response_text = "Custom response" + + # Send manually + await sms_channel.send_response(response_text, context) + + # Return None to prevent auto-send + return None +``` + +## Error Handling + +Channels handle errors gracefully: + +```python +async def handle_message(user_message, context, memory_response): + try: + # Your logic + return "Success" + except Exception as e: + # Channel logs error but doesn't crash + return "Sorry, something went wrong. Please try again." +``` + +## Next Steps + +- [Memory Management](memory.md) - Memory retrieval strategies +- [Server Setup](server.md) - Deploying with channels +- [Architecture](architecture.md) - How channels work internally diff --git a/docs/guides/memory.md b/docs/guides/memory.md new file mode 100644 index 0000000..711ce1c --- /dev/null +++ b/docs/guides/memory.md @@ -0,0 +1,10 @@ +# Memory Management + +(Coming soon) + +This guide will cover: + +- Memory retrieval modes +- Semantic search strategies +- Cache management +- Memory Store configuration diff --git a/docs/guides/openai-adapter.md b/docs/guides/openai-adapter.md new file mode 100644 index 0000000..a074b42 --- /dev/null +++ b/docs/guides/openai-adapter.md @@ -0,0 +1,10 @@ +# OpenAI Adapter + +(Coming soon) + +This guide will cover: + +- Chat Completions API integration +- Responses API integration +- Memory injection +- Streaming support diff --git a/docs/guides/server.md b/docs/guides/server.md new file mode 100644 index 0000000..3af6fb7 --- /dev/null +++ b/docs/guides/server.md @@ -0,0 +1,10 @@ +# Server Setup + +(Coming soon) + +This guide will cover: + +- TACFastAPIServer configuration +- Deployment options +- Production considerations +- Scaling strategies diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..ede7015 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,135 @@ +# Twilio Agent Connect Python SDK + +
+ TAC Logo +
+ +A powerful SDK for building intelligent, context-aware AI agents with Twilio's communication technologies. + +[![Python SDK](https://img.shields.io/badge/Python-3.10+-3776AB.svg)](https://github.com/twilio/twilio-agent-connect-python) +[![PyPI](https://img.shields.io/pypi/v/twilio-agent-connect.svg)](https://pypi.org/project/twilio-agent-connect/) +[![CI](https://github.com/twilio/twilio-agent-connect-python/actions/workflows/ci.yml/badge.svg)](https://github.com/twilio/twilio-agent-connect-python/actions/workflows/ci.yml) +[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/twilio/twilio-agent-connect-python/blob/main/LICENSE) + +--- + +## Overview + +Seamlessly integrate with Twilio Conversation Memory and Conversation Orchestrator to build LLM-powered agents with persistent memory and conversation context. + +!!! tip "Building AI agents on AWS or Microsoft?" + Connect them to Twilio's voice, messaging, and conversation context with these dedicated packages: + + - **[TAC for AWS](https://github.com/twilio/twilio-agent-connect-aws)** — Strands, Bedrock Agents, Bedrock AgentCore + - **[TAC for Microsoft](https://github.com/twilio/twilio-agent-connect-microsoft)** — Microsoft Agent Framework, Azure AI Foundry (incl. Voice Live), Azure OpenAI + +## Key Features + +- **Multi-Channel Support**: Built-in handling for Voice (ConversationRelay), SMS, RCS, WhatsApp, and Chat +- **Outbound Conversations**: Agent-initiated conversations across all supported channels +- **ConversationRelay-Only Mode**: Get started quickly with TAC's voice plumbing (TwiML, WebSocket, callbacks) before adding Conversation Orchestrator or Conversation Memory +- **Memory Management**: Automatic integration with Twilio Conversation Memory for persistent user context +- **Conversation Lifecycle**: Automatic tracking of conversation sessions and state +- **Human Handoff**: Built-in tool to route conversations to human agents via Twilio Studio Flows (including Flex) + +## Installation + +=== "Basic Installation" + ```bash + pip install twilio-agent-connect + ``` + +=== "With Server Support" + ```bash + pip install "twilio-agent-connect[server]" + ``` + +!!! note "Requirements" + TAC requires **Python 3.10 or newer**. + +## Quick Start + +Here's a minimal example to get you started: + +```python +from dotenv import load_dotenv +from openai import AsyncOpenAI +from tac import TAC, TACConfig +from tac.adapters.openai import with_tac_memory +from tac.channels.sms import SMSChannel +from tac.channels.voice import VoiceChannel +from tac.server import TACFastAPIServer + +load_dotenv() + +tac = TAC(config=TACConfig.from_env()) +voice_channel = VoiceChannel(tac) +sms_channel = SMSChannel(tac) +openai_client = AsyncOpenAI() + +conversation_history = {} +SYSTEM_INSTRUCTIONS = ( + "You are a customer service agent speaking with a user over voice or SMS. " + "Keep responses short and conversational — a sentence or two. " + "Do not use markdown, asterisks, bullets, or emojis; your words will be " + "spoken aloud or sent as plain text." +) + +async def handle_message_ready(user_message, context, memory_response): + conv_id = context.conversation_id + + if conv_id not in conversation_history: + conversation_history[conv_id] = [] + conversation_history[conv_id].append({"role": "user", "content": user_message}) + + client = with_tac_memory(openai_client, memory_response, context) + + response = await client.responses.create( + model="gpt-5.4-mini", + instructions=SYSTEM_INSTRUCTIONS, + input=conversation_history[conv_id] + ) + + llm_response = response.output_text + conversation_history[conv_id].append({"role": "assistant", "content": llm_response}) + + return llm_response + +tac.on_message_ready(handle_message_ready) +TACFastAPIServer(tac=tac, voice_channel=voice_channel, messaging_channels=[sms_channel]).start() +``` + +**That's it!** The server automatically: + +- Creates FastAPI app with `/twiml`, `/ws`, and `/webhook` endpoints +- Handles Voice, SMS, RCS, WhatsApp, and Chat conversations +- Routes responses to the appropriate channel +- Injects conversation memory and user profile into OpenAI calls + +For detailed setup instructions, see the [Getting Started Guide](getting-started/index.md). + +## How It Works + +TAC simplifies building AI agents by handling the integration between Twilio's communication channels and your LLM: + +1. **Webhook/Connection Received**: Twilio sends webhook (SMS) or WebSocket connection (Voice) to your server +2. **Channel Processing**: Channel validates and processes the incoming event +3. **Memory Retrieval**: TAC optionally retrieves user memories and profile from Memory +4. **Callback Invoked**: Your `on_message_ready` callback receives user message, context, and optional memory response +5. **Response Handling**: Your callback returns a response string that TAC routes to the appropriate channel + +## Next Steps + +- [Installation Guide](getting-started/installation.md) +- [Quick Start Tutorial](getting-started/quickstart.md) +- [Architecture Overview](guides/architecture.md) +- [Examples](examples/index.md) +- [API Reference](api/core.md) + +## Learn More + +- **[GitHub Repository](https://github.com/twilio/twilio-agent-connect-python)** - Source code and examples +- **[Official Documentation](https://www.twilio.com/docs/conversations/agent-connect)** - Twilio's official docs +- **[PyPI Package](https://pypi.org/project/twilio-agent-connect/)** - Package registry +- **[TAC for AWS](https://github.com/twilio/twilio-agent-connect-aws)** - AWS integrations +- **[TAC for Microsoft](https://github.com/twilio/twilio-agent-connect-microsoft)** - Microsoft integrations diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 0000000..3b8b9a1 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,104 @@ +site_name: Twilio Agent Connect Python SDK +site_description: A powerful SDK for building intelligent, context-aware AI agents with Twilio's communication technologies +site_url: https://twilio.github.io/twilio-agent-connect-python/ +repo_url: https://github.com/twilio/twilio-agent-connect-python +repo_name: twilio/twilio-agent-connect-python +edit_uri: edit/main/docs/ + +theme: + name: material + palette: + # Light mode + - scheme: default + primary: red + accent: red + toggle: + icon: material/brightness-7 + name: Switch to dark mode + # Dark mode + - scheme: slate + primary: red + accent: red + toggle: + icon: material/brightness-4 + name: Switch to light mode + features: + - navigation.tabs + - navigation.sections + - navigation.expand + - navigation.top + - search.suggest + - search.highlight + - content.tabs.link + - content.code.annotation + - content.code.copy + logo: https://raw.githubusercontent.com/twilio/twilio-agent-connect-python/main/logo.svg + favicon: https://raw.githubusercontent.com/twilio/twilio-agent-connect-python/main/logo.svg + +plugins: + - search + - mkdocstrings: + handlers: + python: + paths: [src] + options: + docstring_style: google + show_source: true + show_root_heading: true + show_symbol_type_heading: true + show_symbol_type_toc: true + members_order: source + +markdown_extensions: + - pymdownx.highlight: + anchor_linenums: true + line_spans: __span + pygments_lang_class: true + - pymdownx.inlinehilite + - pymdownx.snippets + - pymdownx.superfences + - pymdownx.tabbed: + alternate_style: true + - admonition + - pymdownx.details + - pymdownx.emoji: + emoji_index: !!python/name:material.extensions.emoji.twemoji + emoji_generator: !!python/name:material.extensions.emoji.to_svg + - attr_list + - md_in_html + - toc: + permalink: true + +nav: + - Home: index.md + - Getting Started: + - Overview: getting-started/index.md + - Installation: getting-started/installation.md + - Quick Start: getting-started/quickstart.md + - Twilio Setup: getting-started/twilio-setup.md + - Guides: + - Architecture: guides/architecture.md + - Channels: guides/channels.md + - Memory Management: guides/memory.md + - OpenAI Adapter: guides/openai-adapter.md + - Server Setup: guides/server.md + - Examples: + - Overview: examples/index.md + - OpenAI Integration: examples/openai.md + - AWS Integration: examples/aws.md + - API Reference: + - Core: api/core.md + - Channels: api/channels.md + - Models: api/models.md + - Adapters: api/adapters.md + - Server: api/server.md + - Contributing: contributing.md + +extra: + social: + - icon: fontawesome/brands/github + link: https://github.com/twilio/twilio-agent-connect-python + - icon: fontawesome/brands/python + link: https://pypi.org/project/twilio-agent-connect/ + version: + provider: mike From f8e706b6b0e6244be01d1faeafba83aa3b733abc Mon Sep 17 00:00:00 2001 From: jahuang Date: Mon, 18 May 2026 11:17:14 -0700 Subject: [PATCH 2/7] Simplify docs to API reference only - Remove getting-started, guides, examples sections - Keep only API reference documentation - Update home page to focus on API docs - Clean navigation structure --- docs/README.md | 77 -------- docs/contributing.md | 1 - docs/examples/aws.md | 9 - docs/examples/index.md | 152 --------------- docs/examples/openai.md | 10 - docs/getting-started/index.md | 33 ---- docs/getting-started/installation.md | 74 -------- docs/getting-started/quickstart.md | 242 ------------------------ docs/getting-started/twilio-setup.md | 132 ------------- docs/guides/architecture.md | 192 ------------------- docs/guides/channels.md | 269 --------------------------- docs/guides/memory.md | 10 - docs/guides/openai-adapter.md | 10 - docs/guides/server.md | 10 - docs/index.md | 24 +-- mkdocs.yml | 16 -- 16 files changed, 8 insertions(+), 1253 deletions(-) delete mode 100644 docs/README.md delete mode 100644 docs/contributing.md delete mode 100644 docs/examples/aws.md delete mode 100644 docs/examples/index.md delete mode 100644 docs/examples/openai.md delete mode 100644 docs/getting-started/index.md delete mode 100644 docs/getting-started/installation.md delete mode 100644 docs/getting-started/quickstart.md delete mode 100644 docs/getting-started/twilio-setup.md delete mode 100644 docs/guides/architecture.md delete mode 100644 docs/guides/channels.md delete mode 100644 docs/guides/memory.md delete mode 100644 docs/guides/openai-adapter.md delete mode 100644 docs/guides/server.md diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 5864b2f..0000000 --- a/docs/README.md +++ /dev/null @@ -1,77 +0,0 @@ -# TAC Documentation - -This directory contains the source for the TAC documentation site. - -## Local Development - -### Prerequisites - -Install dependencies: - -```bash -pip install -r docs-requirements.txt -``` - -Or use the project's uv environment: - -```bash -uv pip install mkdocs-material 'mkdocstrings[python]' pymdown-extensions -``` - -### Build and Serve - -Build the docs: - -```bash -mkdocs build -``` - -Serve locally with hot reload: - -```bash -mkdocs serve -``` - -Visit `http://127.0.0.1:8000` to view the docs. - -### Project Structure - -``` -docs/ -├── index.md # Homepage -├── getting-started/ # Installation and setup guides -├── guides/ # In-depth guides -├── examples/ # Code examples -├── api/ # API reference -└── contributing.md # Contributing guide -``` - -### Adding New Pages - -1. Create a new `.md` file in the appropriate directory -2. Add it to `nav` in `mkdocs.yml` -3. Build and verify - -## Deployment - -### GitHub Actions (Automated) - -Docs are automatically deployed to GitHub Pages when changes are pushed to `main` via the `.github/workflows/docs.yml` workflow. - -You can also trigger manually: -1. Go to: https://github.com/twilio/twilio-agent-connect-python/actions/workflows/docs.yml -2. Click "Run workflow" → Select `main` branch → "Run workflow" - -### Enable GitHub Pages (One-time Setup) - -1. Go to: https://github.com/twilio/twilio-agent-connect-python/settings/pages -2. **Source**: Deploy from a branch -3. **Branch**: `gh-pages` → `/ (root)` -4. Click **Save** -5. Wait 1-2 minutes for deployment - -**Live URL**: https://twilio.github.io/twilio-agent-connect-python/ - -## Contributing - -See [CONTRIBUTING.md](../CONTRIBUTING.md) for contribution guidelines. diff --git a/docs/contributing.md b/docs/contributing.md deleted file mode 100644 index ea38c9b..0000000 --- a/docs/contributing.md +++ /dev/null @@ -1 +0,0 @@ ---8<-- "CONTRIBUTING.md" diff --git a/docs/examples/aws.md b/docs/examples/aws.md deleted file mode 100644 index 680e927..0000000 --- a/docs/examples/aws.md +++ /dev/null @@ -1,9 +0,0 @@ -# AWS Examples - -(Coming soon) - -Examples will cover: - -- AWS Bedrock Agent -- AWS Bedrock AgentCore -- AWS Strands diff --git a/docs/examples/index.md b/docs/examples/index.md deleted file mode 100644 index 6f5fae8..0000000 --- a/docs/examples/index.md +++ /dev/null @@ -1,152 +0,0 @@ -# Examples - -TAC comes with comprehensive examples demonstrating various integration patterns and use cases. - -## Example Repository Structure - -All examples are located in the [`getting_started/examples`](https://github.com/twilio/twilio-agent-connect-python/tree/main/getting_started/examples) directory: - -``` -getting_started/examples/ -├── partners/ # Partner SDK integrations -│ ├── openai_*.py # OpenAI examples -│ ├── bedrock_*.py # AWS Bedrock examples -│ └── strands_*.py # AWS Strands examples -└── features/ # Feature-specific examples - ├── chat/ # Chat channel - ├── dashboard/ # Monitoring dashboard - └── relay_only.py # ConversationRelay-only mode -``` - -## Partner Integrations - -### OpenAI - -- [OpenAI Chat Completions](openai.md#chat-completions-api) - Using the Chat Completions API -- [OpenAI Responses API](openai.md#responses-api) - Using the new Responses API -- [OpenAI Agents SDK](openai.md#agents-sdk) - Integrating with OpenAI Agents - -### AWS - -- [AWS Bedrock Agent](aws.md#bedrock-agent) - AWS Bedrock Agent integration -- [AWS Bedrock AgentCore](aws.md#bedrock-agentcore) - AWS Bedrock AgentCore integration -- [AWS Strands](aws.md#strands) - AWS Strands agent integration - -## Feature Examples - -### ConversationRelay-Only Mode - -Start with just voice (no Orchestrator or Memory): - -```python -from tac import TAC, TACConfig -from tac.channels.voice import VoiceChannel - -config = TACConfig( - api_key=os.getenv("TWILIO_API_KEY"), - api_token=os.getenv("TWILIO_API_TOKEN"), - # No conversation_configuration_id -) - -tac = TAC(config=config) -voice_channel = VoiceChannel(tac) - -# Your voice handling logic -``` - -[View full example →](https://github.com/twilio/twilio-agent-connect-python/blob/main/getting_started/examples/features/relay_only.py) - -### Multi-Channel Support - -Handle Voice, SMS, WhatsApp, and RCS simultaneously: - -```python -from tac.channels.voice import VoiceChannel -from tac.channels.sms import SMSChannel -from tac.channels.whatsapp import WhatsAppChannel -from tac.channels.rcs import RCSChannel -from tac.server import TACFastAPIServer - -TACFastAPIServer( - tac=tac, - voice_channel=VoiceChannel(tac), - messaging_channels=[ - SMSChannel(tac), - WhatsAppChannel(tac), - RCSChannel(tac) - ] -).start() -``` - -### Memory Modes - -```python -# Always fetch memory with semantic search on every message -voice_channel = VoiceChannel(tac, memory_mode="always") - -# Fetch memory once at conversation start -sms_channel = SMSChannel(tac, memory_mode="once") - -# Never fetch memory automatically -whatsapp_channel = WhatsAppChannel(tac, memory_mode="never") -``` - -### Custom Tools - -```python -from tac.tools import function_tool - -@function_tool -async def check_weather(location: str) -> str: - """Check the weather for a location.""" - # Your weather API logic - return f"The weather in {location} is sunny" - -@function_tool -async def book_appointment(date: str, time: str) -> str: - """Book an appointment.""" - # Your booking logic - return f"Appointment booked for {date} at {time}" - -# Use with OpenAI -tools = [ - check_weather.to_openai_tool(), - book_appointment.to_openai_tool() -] - -response = await client.responses.create( - model="gpt-5.4-mini", - instructions=INSTRUCTIONS, - input=messages, - tools=tools -) -``` - -## Running Examples - -Clone the repository and install dependencies: - -```bash -git clone https://github.com/twilio/twilio-agent-connect-python.git -cd twilio-agent-connect-python -make sync -``` - -Configure your environment: - -```bash -cp .env.example .env -# Edit .env with your credentials -``` - -Run an example: - -```bash -uv run getting_started/examples/partners/openai_chat_completions.py -``` - -## Next Steps - -- [OpenAI Examples](openai.md) - Detailed OpenAI integration guides -- [AWS Examples](aws.md) - AWS Bedrock and Strands examples -- [API Reference](../api/core.md) - Complete API documentation diff --git a/docs/examples/openai.md b/docs/examples/openai.md deleted file mode 100644 index d668349..0000000 --- a/docs/examples/openai.md +++ /dev/null @@ -1,10 +0,0 @@ -# OpenAI Examples - -(Coming soon) - -Examples will cover: - -- Chat Completions API -- Responses API -- OpenAI Agents SDK -- Streaming responses diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md deleted file mode 100644 index c839884..0000000 --- a/docs/getting-started/index.md +++ /dev/null @@ -1,33 +0,0 @@ -# Getting Started - -Welcome to Twilio Agent Connect! This guide will help you set up TAC and build your first AI agent. - -## Prerequisites - -- Python 3.10 or newer -- A Twilio account ([Sign up here](https://www.twilio.com/try-twilio)) -- Basic familiarity with Python async/await - -## Setup Options - -TAC offers two ways to get started: - -### Option 1: Setup Wizard (Recommended) - -Use the [Twilio Setup Wizard](twilio-setup.md) to automatically create a Memory Store and Conversation Configuration and generate your `.env` file: - -```bash -git clone https://github.com/twilio/twilio-agent-connect-python.git -cd twilio-agent-connect-python -make setup # Open http://localhost:8080 -``` - -### Option 2: Manual Setup - -You can also create a Memory Store and Conversation Configuration manually through the [Twilio Console](https://console.twilio.com). For a full walkthrough — credentials, Console navigation, and webhook configuration — see the [TAC Quickstart](https://www.twilio.com/docs/conversations/agent-connect/quickstart). - -## What's Next? - -- [Installation Guide](installation.md) - Install TAC in your project -- [Quick Start](quickstart.md) - Build your first agent -- [Twilio Setup](twilio-setup.md) - Configure Twilio services diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md deleted file mode 100644 index b79b435..0000000 --- a/docs/getting-started/installation.md +++ /dev/null @@ -1,74 +0,0 @@ -# Installation - -## Requirements - -- Python 3.10 or newer -- pip or uv package manager - -## Install from PyPI - -### Basic Installation - -For basic TAC functionality (channels, memory, adapters): - -```bash -pip install twilio-agent-connect -``` - -### With Server Support - -To include the FastAPI-based `TACFastAPIServer`: - -```bash -pip install "twilio-agent-connect[server]" -``` - -This installs additional dependencies: - -- `fastapi>=0.115.0` -- `uvicorn[standard]>=0.32.0` -- `python-multipart>=0.0.20` - -## Install from Source - -For development or to try the latest features: - -```bash -git clone https://github.com/twilio/twilio-agent-connect-python.git -cd twilio-agent-connect-python -make sync # Installs via uv -``` - -## Verify Installation - -```python -import tac -print(f"TAC version: {tac.__version__}") -``` - -## Additional Dependencies - -Depending on your use case, you may need additional packages: - -### For OpenAI Integration - -```bash -pip install openai python-dotenv -``` - -### For AWS Integration - -```bash -pip install boto3 boto3-stubs[bedrock-agent-runtime,bedrock-agentcore] strands-agents -``` - -### For Development - -```bash -pip install pytest pytest-asyncio ruff mypy -``` - -## Next Steps - -- [Quick Start Guide](quickstart.md) - Build your first agent -- [Twilio Setup](twilio-setup.md) - Configure Twilio services diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md deleted file mode 100644 index a78a21e..0000000 --- a/docs/getting-started/quickstart.md +++ /dev/null @@ -1,242 +0,0 @@ -# Quick Start - -This guide will walk you through building your first TAC-powered AI agent in under 10 minutes. - -## Prerequisites - -Before starting, ensure you have: - -- Python 3.10+ installed -- A Twilio account with API credentials -- Completed the [Twilio Setup](twilio-setup.md) (or have Memory Store and Conversation Configuration IDs) - -## Step 1: Install TAC - -```bash -pip install "twilio-agent-connect[server]" openai python-dotenv -``` - -## Step 2: Configure Environment - -Create a `.env` file with your Twilio credentials: - -```bash -# Twilio credentials -TWILIO_API_KEY=your_api_key -TWILIO_API_TOKEN=your_api_token -TWILIO_ACCOUNT_SID=your_account_sid - -# TAC configuration -CONVERSATION_CONFIGURATION_ID=your_config_id - -# OpenAI -OPENAI_API_KEY=your_openai_key -``` - -## Step 3: Create Your Agent - -Create `app.py`: - -```python -from dotenv import load_dotenv -from openai import AsyncOpenAI -from tac import TAC, TACConfig -from tac.adapters.openai import with_tac_memory -from tac.channels.sms import SMSChannel -from tac.channels.voice import VoiceChannel -from tac.server import TACFastAPIServer - -load_dotenv() - -# Initialize TAC -tac = TAC(config=TACConfig.from_env()) -voice_channel = VoiceChannel(tac) -sms_channel = SMSChannel(tac) -openai_client = AsyncOpenAI() - -# Store conversation history per conversation -conversation_history = {} - -SYSTEM_INSTRUCTIONS = ( - "You are a helpful customer service agent. " - "Keep responses short and conversational. " - "Do not use markdown or emojis." -) - -async def handle_message_ready(user_message, context, memory_response): - """Called when a message is ready for processing.""" - conv_id = context.conversation_id - - # Initialize or retrieve conversation history - if conv_id not in conversation_history: - conversation_history[conv_id] = [] - - conversation_history[conv_id].append({ - "role": "user", - "content": user_message - }) - - # Wrap OpenAI client with TAC memory injection - client = with_tac_memory(openai_client, memory_response, context) - - # Generate response - response = await client.responses.create( - model="gpt-5.4-mini", - instructions=SYSTEM_INSTRUCTIONS, - input=conversation_history[conv_id] - ) - - llm_response = response.output_text - conversation_history[conv_id].append({ - "role": "assistant", - "content": llm_response - }) - - return llm_response - -# Register callback -tac.on_message_ready(handle_message_ready) - -# Start server -TACFastAPIServer( - tac=tac, - voice_channel=voice_channel, - messaging_channels=[sms_channel] -).start() -``` - -## Step 4: Run Your Agent - -```bash -python app.py -``` - -Your server will start on `http://localhost:8000` with these endpoints: - -- `/twiml` - Voice call entry point -- `/ws` - WebSocket for ConversationRelay -- `/webhook` - Messaging webhooks (SMS, WhatsApp, etc.) - -## Step 5: Test It Out - -### Option A: Use ngrok for Testing - -```bash -# Install ngrok -brew install ngrok # macOS -# or download from https://ngrok.com/ - -# Expose your local server -ngrok http 8000 -``` - -Configure your Twilio phone number webhooks to point to your ngrok URL: - -- Voice: `https://your-ngrok-url.ngrok.io/twiml` -- SMS: `https://your-ngrok-url.ngrok.io/webhook` - -### Option B: Deploy to Production - -See the [Server Setup Guide](../guides/server.md) for deployment options. - -## What Just Happened? - -Let's break down the code: - -1. **TAC Initialization**: Loads configuration from environment variables -2. **Channel Setup**: Creates Voice and SMS channels -3. **Callback Registration**: `on_message_ready` processes each message -4. **Memory Injection**: `with_tac_memory()` automatically adds user context to OpenAI calls -5. **Server Creation**: `TACFastAPIServer` handles all webhook routing - -## Next Steps - -### Add More Channels - -```python -from tac.channels.whatsapp import WhatsAppChannel -from tac.channels.rcs import RCSChannel - -whatsapp = WhatsAppChannel(tac) -rcs = RCSChannel(tac) - -TACFastAPIServer( - tac=tac, - voice_channel=voice_channel, - messaging_channels=[sms_channel, whatsapp, rcs] -).start() -``` - -### Enable Memory Retrieval - -Configure when to fetch user memories: - -```python -voice_channel = VoiceChannel(tac, memory_mode="always") -sms_channel = SMSChannel(tac, memory_mode="once") -``` - -Options: - -- `"never"` (default): No memory retrieval -- `"always"`: Fetch on every message with semantic search -- `"once"`: Fetch once at conversation start, cache results - -### Add Tools - -Give your agent capabilities: - -```python -from tac.tools import function_tool - -@function_tool -async def get_order_status(order_id: str) -> str: - """Check the status of an order.""" - # Your logic here - return f"Order {order_id} is in transit" - -# Use with OpenAI -tools = [get_order_status.to_openai_tool()] -``` - -### Handle Conversation End - -```python -async def handle_conversation_ended(context): - """Called when conversation ends.""" - conv_id = context.conversation_id - if conv_id in conversation_history: - del conversation_history[conv_id] - print(f"Conversation {conv_id} ended") - -tac.on_conversation_ended(handle_conversation_ended) -``` - -## Common Issues - -### "Configuration not found" - -Make sure your `.env` file contains valid IDs and your Twilio credentials are correct. - -### "Port 8000 already in use" - -Change the port: - -```python -TACFastAPIServer(...).start(host="0.0.0.0", port=8080) -``` - -### Memory not working - -Verify: - -1. Your Conversation Configuration has a Memory Store configured -2. Memory mode is set to `"always"` or `"once"` -3. Your Twilio account has Conversation Memory enabled - -## Learn More - -- [Architecture Guide](../guides/architecture.md) - Understand how TAC works -- [Channels Guide](../guides/channels.md) - Deep dive into channels -- [Memory Management](../guides/memory.md) - Memory retrieval strategies -- [Examples](../examples/index.md) - More code examples diff --git a/docs/getting-started/twilio-setup.md b/docs/getting-started/twilio-setup.md deleted file mode 100644 index 4614afc..0000000 --- a/docs/getting-started/twilio-setup.md +++ /dev/null @@ -1,132 +0,0 @@ -# Twilio Setup - -This guide covers setting up the required Twilio resources for TAC. - -## Prerequisites - -- A Twilio account ([Sign up here](https://www.twilio.com/try-twilio)) -- Twilio API credentials (API Key and Secret) - -## Option 1: Setup Wizard (Recommended) - -The easiest way to get started is using our setup wizard: - -```bash -git clone https://github.com/twilio/twilio-agent-connect-python.git -cd twilio-agent-connect-python -make setup -``` - -This opens a web interface at `http://localhost:8080` that will: - -1. Create a Memory Store -2. Create a Conversation Configuration -3. Link them together -4. Generate your `.env` file - -## Option 2: Manual Setup - -### Step 1: Create API Credentials - -1. Go to [Twilio Console - API Keys](https://console.twilio.com/us1/account/keys-credentials/api-keys) -2. Click "Create API Key" -3. Name it (e.g., "TAC Development") -4. Save the SID (API Key) and Secret (API Token) securely - -### Step 2: Create a Memory Store - -1. Go to [Conversation Memory Console](https://console.twilio.com/us1/develop/conversations/memory) -2. Click "Create Memory Store" -3. Configure your store: - - **Name**: e.g., "TAC Memory Store" - - **Description**: Optional -4. Save the Memory Store SID - -### Step 3: Create a Conversation Configuration - -1. Go to [Conversation Orchestrator Console](https://console.twilio.com/us1/develop/conversations/orchestrator) -2. Click "Create Configuration" -3. Configure: - - **Name**: e.g., "TAC Configuration" - - **Memory Store**: Select the store from Step 2 - - **Other settings**: Configure as needed -4. Save the Configuration SID - -### Step 4: Configure Environment - -Create a `.env` file: - -```bash -# Twilio Account -TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxx -TWILIO_API_KEY=SKxxxxxxxxxxxxxxxxxxxxxxxxxxxx -TWILIO_API_TOKEN=your_api_token - -# TAC Configuration -CONVERSATION_CONFIGURATION_ID=OCxxxxxxxxxxxxxxxxxxxxxxxxxxxx - -# Optional: For voice -TWILIO_PHONE_NUMBER=+1234567890 - -# Optional: For OpenAI integration -OPENAI_API_KEY=sk-... -``` - -### Step 5: Set Up Phone Number Webhooks - -For Voice: - -1. Go to [Phone Numbers](https://console.twilio.com/us1/develop/phone-numbers/manage/incoming) -2. Select your number -3. Under "Voice Configuration": - - **A CALL COMES IN**: Webhook, `https://your-domain.com/twiml`, HTTP POST - -For SMS: - -1. Same phone number settings -2. Under "Messaging Configuration": - - **A MESSAGE COMES IN**: Webhook, `https://your-domain.com/webhook`, HTTP POST - -For WhatsApp: - -1. Go to [WhatsApp Senders](https://console.twilio.com/us1/develop/sms/senders/whatsapp-senders) -2. Select your sender -3. Configure webhook: `https://your-domain.com/webhook` - -## Verify Setup - -Test your configuration: - -```python -from tac import TAC, TACConfig - -config = TACConfig.from_env() -tac = TAC(config=config) - -# Check if Orchestrator is enabled -print(f"Orchestrator enabled: {tac.is_orchestrator_enabled()}") -``` - -## Troubleshooting - -### "Invalid API credentials" - -- Verify API Key and Token are correct -- Check that API Key is active in Twilio Console -- Ensure Account SID matches the account that created the API Key - -### "Configuration not found" - -- Verify `CONVERSATION_CONFIGURATION_ID` is correct -- Check that the configuration exists and is active -- Ensure your API credentials have access to the configuration - -### "Memory Store not found" - -- Verify the Memory Store is linked to your Conversation Configuration -- Check Memory Store status in Twilio Console - -## Next Steps - -- [Quick Start Guide](quickstart.md) - Build your first agent -- [Installation](installation.md) - Install TAC diff --git a/docs/guides/architecture.md b/docs/guides/architecture.md deleted file mode 100644 index 0253436..0000000 --- a/docs/guides/architecture.md +++ /dev/null @@ -1,192 +0,0 @@ -# Architecture - -TAC is designed as middleware that connects Twilio's communication channels with your LLM application. Understanding the architecture helps you build more effective agents. - -## Core Components - -### TAC Class - -The central orchestrator that coordinates all components: - -```python -from tac import TAC, TACConfig - -tac = TAC(config=TACConfig.from_env()) -``` - -Key responsibilities: - -- Configuration management -- Memory retrieval coordination -- Callback registration and invocation -- Profile resolution - -### Channels - -Channels handle communication protocol specifics: - -- **Voice**: ConversationRelay WebSocket handling, TwiML generation -- **SMS**: SMS webhook processing -- **RCS**: RCS webhook processing with rich media -- **WhatsApp**: WhatsApp webhook processing -- **Chat**: Multi-platform chat handling - -Each channel: - -1. Validates incoming webhooks/connections -2. Manages conversation lifecycle -3. Triggers TAC callbacks -4. Routes responses back to Twilio - -### Memory System - -TAC integrates with Twilio Conversation Memory: - -- **Automatic initialization** from Conversation Orchestrator config -- **Three retrieval modes**: - - `"never"` (default): No automatic retrieval - - `"always"`: Fetch on every message with semantic search - - `"once"`: Fetch once, cache until conversation state changes -- **Graceful fallback** to Conversation Orchestrator if Memory unavailable - -### Adapters - -Adapters inject TAC context into LLM SDKs: - -- **OpenAI Adapter**: Memory injection for Chat Completions and Responses APIs -- Automatically formats memory and profile for LLM consumption -- Supports sync/async and streaming - -## Message Flow - -```mermaid -sequenceDiagram - participant User - participant Twilio - participant Channel - participant TAC - participant Memory - participant Callback - participant LLM - - User->>Twilio: Send message/call - Twilio->>Channel: Webhook/WebSocket - Channel->>TAC: Process message - TAC->>Memory: Retrieve context (optional) - Memory-->>TAC: User memories + profile - TAC->>Callback: on_message_ready - Callback->>LLM: Generate response - LLM-->>Callback: Response text - Callback-->>TAC: Return response - TAC->>Channel: Route response - Channel->>Twilio: Send via API - Twilio->>User: Deliver message -``` - -## Conversation Lifecycle - -### Connection Phase - -1. Twilio receives user message/call -2. Channel validates and processes -3. Profile lookup (if needed) -4. Memory retrieval (based on mode) -5. Conversation stored in `_conversations` - -### Active Phase - -- Messages flow through `on_message_ready` -- Memory cache maintained (for `"once"` mode) -- State tracked per conversation - -### Cleanup Phase - -- Voice: On WebSocket disconnect -- Messaging: On INACTIVE status or conversation end -- Memory cache cleared -- Conversation removed from tracking - -## ConversationRelay-Only Mode - -TAC can run without Conversation Orchestrator or Memory: - -```python -config = TACConfig( - api_key=os.getenv("TWILIO_API_KEY"), - api_token=os.getenv("TWILIO_API_TOKEN"), - # No conversation_configuration_id -) -``` - -In this mode: - -- Only Voice channel works (messaging channels raise at construction) -- `retrieve_memory()` returns empty response -- ConversationRelay callback handles session cleanup -- Perfect for voice-first prototypes - -Check at runtime: - -```python -if tac.is_orchestrator_enabled(): - # Use memory features -else: - # Voice-only mode -``` - -## Scaling Considerations - -### Single Instance - -TAC works perfectly out of the box for single-instance deployments: - -- Conversation tracking in memory (`self._conversations`) -- Automatic cleanup on disconnect/inactivity -- No shared state needed - -### Multi-Instance (Horizontal Scaling) - -Current architecture has limitations: - -- Conversation state is instance-local -- Webhooks may route to different instances -- Can cause memory leaks (conversations not cleaned up) - -**Recommended solutions:** - -1. **Sticky sessions**: Configure load balancer to route by `conversation_id` -2. **Shared state**: Use Redis or database for `_conversations` tracking - -## Key Architecture Patterns - -### Memory Fallback Chain - -1. Try Conversation Memory first -2. Fall back to Orchestrator's `list_communications()` -3. Return empty response if both fail -4. Never block callback execution - -### Profile Resolution - -1. Check if `profile_id` in webhook -2. If missing, look up by phone/email -3. Create profile if lookup fails -4. Cache in context for callback - -### Async-First Design - -- All I/O operations use `httpx.AsyncClient` -- Callbacks are async by default -- Channels handle both sync/async gracefully - -### Error Handling Philosophy - -- API failures should not crash the agent -- Log errors, return empty/default values -- Let callbacks decide how to handle missing data - -## Next Steps - -- [Channels Guide](channels.md) - Deep dive into channel implementations -- [Memory Management](memory.md) - Memory retrieval strategies -- [Server Setup](server.md) - Deploying TAC applications diff --git a/docs/guides/channels.md b/docs/guides/channels.md deleted file mode 100644 index 4e330c6..0000000 --- a/docs/guides/channels.md +++ /dev/null @@ -1,269 +0,0 @@ -# Channels Guide - -Channels handle the communication protocol specifics for each Twilio platform. This guide covers how to use and configure channels effectively. - -## Available Channels - -TAC provides five built-in channels: - -| Channel | Use Case | Protocol | -|---------|----------|----------| -| **Voice** | Phone calls | ConversationRelay WebSocket + TwiML | -| **SMS** | Text messages | HTTP webhooks | -| **RCS** | Rich messaging | HTTP webhooks | -| **WhatsApp** | WhatsApp Business | HTTP webhooks | -| **Chat** | Multi-platform chat | HTTP webhooks | - -## Basic Usage - -### Single Channel - -```python -from tac import TAC, TACConfig -from tac.channels.sms import SMSChannel - -tac = TAC(config=TACConfig.from_env()) -sms_channel = SMSChannel(tac) - -async def handle_message(user_message, context, memory_response): - return "Hello from SMS!" - -tac.on_message_ready(handle_message) -``` - -### Multiple Channels - -```python -from tac.channels.voice import VoiceChannel -from tac.channels.sms import SMSChannel -from tac.channels.whatsapp import WhatsAppChannel -from tac.server import TACFastAPIServer - -tac = TAC(config=TACConfig.from_env()) - -TACFastAPIServer( - tac=tac, - voice_channel=VoiceChannel(tac), - messaging_channels=[ - SMSChannel(tac), - WhatsAppChannel(tac) - ] -).start() -``` - -## Memory Modes - -All channels support three memory retrieval modes: - -### Never (Default) - -No automatic memory retrieval: - -```python -channel = SMSChannel(tac, memory_mode="never") -``` - -Use when: - -- You don't need memory -- You'll manually call `tac.retrieve_memory()` -- Testing without Memory configured - -### Always - -Fetch memory on every message with semantic search: - -```python -channel = VoiceChannel(tac, memory_mode="always") -``` - -The user's message is used as the query for semantic search. Best for: - -- Conversations where context changes frequently -- When you need the most relevant memories per message - -### Once - -Fetch memory once at conversation start, cache until conversation ends: - -```python -channel = SMSChannel(tac, memory_mode="once") -``` - -Memory is retrieved with an empty query (returns all/recent memories) and cached. Cache is invalidated when: - -- Conversation status becomes INACTIVE -- Conversation ends -- Memory Store updates memories - -Best for: - -- Long conversations with stable context -- Reducing API calls -- Faster response times - -## Voice Channel - -Handles ConversationRelay WebSocket connections and TwiML generation. - -### Configuration - -```python -from tac.channels.voice import VoiceChannel, VoiceConfig - -voice_config = VoiceConfig( - welcome_message="Hello! How can I help you?", - voice="Polly.Joanna-Neural", - language="en-US", - dtmf_detection=True -) - -voice_channel = VoiceChannel(tac, config=voice_config, memory_mode="always") -``` - -### TwiML Generation - -Voice channel automatically generates TwiML for call handling: - -```python -# The /twiml endpoint returns: - - - - - Hello! How can I help you? - -``` - -### WebSocket Handling - -The channel manages the WebSocket lifecycle: - -1. **Connection**: Client connects to `/ws` -2. **Session start**: Receives configuration from Twilio -3. **Media streaming**: Processes audio in/out -4. **Message processing**: Triggers `on_message_ready` for transcripts -5. **Cleanup**: Handles disconnection and conversation end - -### Voice-Specific Callbacks - -```python -async def handle_call_connected(context): - print(f"Call connected: {context.conversation_id}") - -async def handle_call_ended(context): - print(f"Call ended: {context.conversation_id}") - -voice_channel.on_connected(handle_call_connected) -voice_channel.on_ended(handle_call_ended) -``` - -## Messaging Channels - -SMS, RCS, WhatsApp, and Chat channels share similar webhook-based architecture. - -### SMS Channel - -```python -from tac.channels.sms import SMSChannel - -sms_channel = SMSChannel(tac, memory_mode="once") - -async def handle_sms(user_message, context, memory_response): - # Access SMS-specific data - from_number = context.from_ - to_number = context.to - - return f"Received your SMS: {user_message}" - -tac.on_message_ready(handle_sms) -``` - -### WhatsApp Channel - -```python -from tac.channels.whatsapp import WhatsAppChannel - -whatsapp_channel = WhatsAppChannel(tac, memory_mode="always") - -async def handle_whatsapp(user_message, context, memory_response): - # WhatsApp-specific context - from_number = context.from_ # e.g., "whatsapp:+1234567890" - - return "Thanks for your WhatsApp message!" - -tac.on_message_ready(handle_whatsapp) -``` - -### RCS Channel - -Rich Communication Services with media support: - -```python -from tac.channels.rcs import RCSChannel - -rcs_channel = RCSChannel(tac, memory_mode="once") - -async def handle_rcs(user_message, context, memory_response): - # RCS supports rich media - return "RCS response with rich formatting support" - -tac.on_message_ready(handle_rcs) -``` - -## Channel Context - -Each channel provides context in the callback: - -```python -async def handle_message(user_message, context, memory_response): - # Common to all channels - conversation_id = context.conversation_id - profile_id = context.profile_id - - # Channel-specific - from_number = context.from_ - to_number = context.to - - # For voice - if hasattr(context, 'call_sid'): - call_sid = context.call_sid - - return "Response" -``` - -## Manual Response Handling - -By default, returning a string sends it as the response. For manual control, return `None`: - -```python -async def handle_message(user_message, context, memory_response): - # Process message - response_text = "Custom response" - - # Send manually - await sms_channel.send_response(response_text, context) - - # Return None to prevent auto-send - return None -``` - -## Error Handling - -Channels handle errors gracefully: - -```python -async def handle_message(user_message, context, memory_response): - try: - # Your logic - return "Success" - except Exception as e: - # Channel logs error but doesn't crash - return "Sorry, something went wrong. Please try again." -``` - -## Next Steps - -- [Memory Management](memory.md) - Memory retrieval strategies -- [Server Setup](server.md) - Deploying with channels -- [Architecture](architecture.md) - How channels work internally diff --git a/docs/guides/memory.md b/docs/guides/memory.md deleted file mode 100644 index 711ce1c..0000000 --- a/docs/guides/memory.md +++ /dev/null @@ -1,10 +0,0 @@ -# Memory Management - -(Coming soon) - -This guide will cover: - -- Memory retrieval modes -- Semantic search strategies -- Cache management -- Memory Store configuration diff --git a/docs/guides/openai-adapter.md b/docs/guides/openai-adapter.md deleted file mode 100644 index a074b42..0000000 --- a/docs/guides/openai-adapter.md +++ /dev/null @@ -1,10 +0,0 @@ -# OpenAI Adapter - -(Coming soon) - -This guide will cover: - -- Chat Completions API integration -- Responses API integration -- Memory injection -- Streaming support diff --git a/docs/guides/server.md b/docs/guides/server.md deleted file mode 100644 index 3af6fb7..0000000 --- a/docs/guides/server.md +++ /dev/null @@ -1,10 +0,0 @@ -# Server Setup - -(Coming soon) - -This guide will cover: - -- TACFastAPIServer configuration -- Deployment options -- Production considerations -- Scaling strategies diff --git a/docs/index.md b/docs/index.md index ede7015..7329457 100644 --- a/docs/index.md +++ b/docs/index.md @@ -106,25 +106,17 @@ TACFastAPIServer(tac=tac, voice_channel=voice_channel, messaging_channels=[sms_c - Routes responses to the appropriate channel - Injects conversation memory and user profile into OpenAI calls -For detailed setup instructions, see the [Getting Started Guide](getting-started/index.md). +For detailed setup instructions, see the [GitHub README](https://github.com/twilio/twilio-agent-connect-python). -## How It Works +## API Reference -TAC simplifies building AI agents by handling the integration between Twilio's communication channels and your LLM: +Explore the complete API documentation: -1. **Webhook/Connection Received**: Twilio sends webhook (SMS) or WebSocket connection (Voice) to your server -2. **Channel Processing**: Channel validates and processes the incoming event -3. **Memory Retrieval**: TAC optionally retrieves user memories and profile from Memory -4. **Callback Invoked**: Your `on_message_ready` callback receives user message, context, and optional memory response -5. **Response Handling**: Your callback returns a response string that TAC routes to the appropriate channel - -## Next Steps - -- [Installation Guide](getting-started/installation.md) -- [Quick Start Tutorial](getting-started/quickstart.md) -- [Architecture Overview](guides/architecture.md) -- [Examples](examples/index.md) -- [API Reference](api/core.md) +- [Core API](api/core.md) - TAC, TACConfig, context models +- [Channels](api/channels.md) - Voice, SMS, RCS, WhatsApp, Chat +- [Models](api/models.md) - Data models for conversations, memory, sessions +- [Adapters](api/adapters.md) - OpenAI integration +- [Server](api/server.md) - FastAPI server setup ## Learn More diff --git a/mkdocs.yml b/mkdocs.yml index 3b8b9a1..f4f34b4 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -71,28 +71,12 @@ markdown_extensions: nav: - Home: index.md - - Getting Started: - - Overview: getting-started/index.md - - Installation: getting-started/installation.md - - Quick Start: getting-started/quickstart.md - - Twilio Setup: getting-started/twilio-setup.md - - Guides: - - Architecture: guides/architecture.md - - Channels: guides/channels.md - - Memory Management: guides/memory.md - - OpenAI Adapter: guides/openai-adapter.md - - Server Setup: guides/server.md - - Examples: - - Overview: examples/index.md - - OpenAI Integration: examples/openai.md - - AWS Integration: examples/aws.md - API Reference: - Core: api/core.md - Channels: api/channels.md - Models: api/models.md - Adapters: api/adapters.md - Server: api/server.md - - Contributing: contributing.md extra: social: From 20fd2e3a0bb0bf4ca13f03fc3d5c9efa5264a227 Mon Sep 17 00:00:00 2001 From: jahuang Date: Mon, 18 May 2026 11:30:13 -0700 Subject: [PATCH 3/7] Generate API documentation from source code with mkdocstrings - Use mkdocstrings to auto-generate API docs from Python docstrings - Document TAC, TACConfig classes from source - Document all channel classes (Voice, SMS, RCS, WhatsApp, Chat) - Document models module - Document adapters (OpenAI with_tac_memory) - Document server classes (TACFastAPIServer) - Remove placeholder 'Coming soon' content --- docs/api/adapters.md | 11 ++--- docs/api/channels.md | 29 ++++++++--- docs/api/core.md | 114 +++++-------------------------------------- docs/api/models.md | 15 +++--- docs/api/server.md | 11 ++--- 5 files changed, 48 insertions(+), 132 deletions(-) diff --git a/docs/api/adapters.md b/docs/api/adapters.md index 321be2d..5dc05db 100644 --- a/docs/api/adapters.md +++ b/docs/api/adapters.md @@ -1,9 +1,6 @@ # Adapters API Reference -(Coming soon) - -This page will document: - -- OpenAI adapter -- with_tac_memory function -- Memory injection strategies +::: tac.adapters.openai.adapter.with_tac_memory + options: + show_root_heading: true + show_source: false diff --git a/docs/api/channels.md b/docs/api/channels.md index d19e7b9..188e73b 100644 --- a/docs/api/channels.md +++ b/docs/api/channels.md @@ -1,11 +1,26 @@ # Channels API Reference -(Coming soon) +::: tac.channels.voice.VoiceChannel + options: + show_root_heading: true + show_source: false -This page will document: +::: tac.channels.sms.SMSChannel + options: + show_root_heading: true + show_source: false -- VoiceChannel -- SMSChannel -- RCSChannel -- WhatsAppChannel -- ChatChannel +::: tac.channels.rcs.RCSChannel + options: + show_root_heading: true + show_source: false + +::: tac.channels.whatsapp.WhatsAppChannel + options: + show_root_heading: true + show_source: false + +::: tac.channels.chat.ChatChannel + options: + show_root_heading: true + show_source: false diff --git a/docs/api/core.md b/docs/api/core.md index 52e1762..1f6b248 100644 --- a/docs/api/core.md +++ b/docs/api/core.md @@ -1,105 +1,13 @@ # Core API Reference -This page documents the core TAC classes and functions. - -## TAC - -The main orchestrator class that coordinates all TAC components. - -```python -from tac import TAC, TACConfig - -tac = TAC(config=TACConfig.from_env()) -``` - -### Methods - -#### `__init__(config: TACConfig)` - -Initialize a TAC instance with configuration. - -#### `on_message_ready(callback)` - -Register callback for when a message is ready for processing. - -```python -async def handle_message(user_message: str, context, memory_response): - return "Response" - -tac.on_message_ready(handle_message) -``` - -#### `on_conversation_ended(callback)` - -Register callback for when a conversation ends. - -```python -async def handle_ended(context): - print(f"Conversation {context.conversation_id} ended") - -tac.on_conversation_ended(handle_ended) -``` - -#### `retrieve_memory(profile_id, conversation_id, query=None)` - -Manually retrieve memory for a user. - -#### `is_orchestrator_enabled()` - -Check if Conversation Orchestrator is configured. - -## TACConfig - -Configuration for TAC instances. - -```python -from tac import TACConfig - -# From environment -config = TACConfig.from_env() - -# Manual -config = TACConfig( - api_key="SKxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - api_token="your_api_secret_here", - account_sid="ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx", - conversation_configuration_id="conv_configuration_xxxxx" -) -``` - -### Fields - -- `api_key: str` - Twilio API Key SID -- `api_token: str` - Twilio API Token (Secret) -- `account_sid: str` - Twilio Account SID -- `conversation_configuration_id: str | None` - Conversation Configuration SID (optional for ConversationRelay-only mode) - -## Context Models - -### TACContext - -Context information passed to callbacks containing conversation metadata, participant info, and profile data. - -### TACMemoryResponse - -Memory retrieval response containing user memories and profile information. - -## API Clients - -API clients for interacting with Twilio services. These are used internally by TAC but can also be used directly. - -### ConversationClient - -Client for Conversation Orchestrator API. - -### MemoryClient - -Client for Conversation Memory API. - -### KnowledgeClient - -Client for Knowledge Base API. - ---- - -**Note**: Full API reference with type signatures coming soon. For now, see the [source code](https://github.com/twilio/twilio-agent-connect-python/tree/main/src/tac) for detailed implementation. +::: tac.TAC + options: + show_root_heading: true + show_source: false + members_order: source + +::: tac.TACConfig + options: + show_root_heading: true + show_source: false + members_order: source diff --git a/docs/api/models.md b/docs/api/models.md index 09b5219..4e85930 100644 --- a/docs/api/models.md +++ b/docs/api/models.md @@ -1,11 +1,10 @@ # Models API Reference -(Coming soon) +API data models used throughout TAC. -This page will document all Pydantic models: - -- Memory models -- Conversation models -- Session models -- Voice models -- Knowledge models +::: tac.models + options: + show_root_heading: false + show_source: false + members_order: source + group_by_category: true diff --git a/docs/api/server.md b/docs/api/server.md index 4084740..0387d9c 100644 --- a/docs/api/server.md +++ b/docs/api/server.md @@ -1,9 +1,6 @@ # Server API Reference -(Coming soon) - -This page will document: - -- TACFastAPIServer -- Server configuration -- Custom endpoints +::: tac.server.TACFastAPIServer + options: + show_root_heading: true + show_source: false From 0d12640fee0713f1251548d9263b7c3fba817d20 Mon Sep 17 00:00:00 2001 From: jahuang Date: Mon, 18 May 2026 13:23:31 -0700 Subject: [PATCH 4/7] Filter API documentation to show only public methods - Add mkdocstrings filters to exclude private members (_prefix) - Explicitly list public methods for each class: - TAC: __init__, on_message_ready, on_conversation_ended, retrieve_memory, is_orchestrator_enabled - TACConfig: from_env, account_sid, api_key, api_secret, conversation_configuration_id - Channels: __init__, process_webhook/handle_*, send_response - Server: __init__, start, get_app - Hide undocumented members - Set show_source: false globally --- docs/api/adapters.md | 6 +++++- docs/api/channels.md | 41 ++++++++++++++++++++++++++++++++++++----- docs/api/core.md | 22 ++++++++++++++++++---- docs/api/server.md | 8 +++++++- mkdocs.yml | 6 +++++- 5 files changed, 71 insertions(+), 12 deletions(-) diff --git a/docs/api/adapters.md b/docs/api/adapters.md index 5dc05db..2d45e34 100644 --- a/docs/api/adapters.md +++ b/docs/api/adapters.md @@ -1,6 +1,10 @@ # Adapters API Reference +## OpenAI Adapter + +### with_tac_memory + ::: tac.adapters.openai.adapter.with_tac_memory options: - show_root_heading: true + show_root_heading: false show_source: false diff --git a/docs/api/channels.md b/docs/api/channels.md index 188e73b..d930753 100644 --- a/docs/api/channels.md +++ b/docs/api/channels.md @@ -1,26 +1,57 @@ # Channels API Reference +## VoiceChannel + ::: tac.channels.voice.VoiceChannel options: - show_root_heading: true + show_root_heading: false show_source: false + members: + - __init__ + - handle_incoming_call + - handle_websocket + - send_response + +## SMSChannel ::: tac.channels.sms.SMSChannel options: - show_root_heading: true + show_root_heading: false show_source: false + members: + - __init__ + - process_webhook + - send_response + +## RCSChannel ::: tac.channels.rcs.RCSChannel options: - show_root_heading: true + show_root_heading: false show_source: false + members: + - __init__ + - process_webhook + - send_response + +## WhatsAppChannel ::: tac.channels.whatsapp.WhatsAppChannel options: - show_root_heading: true + show_root_heading: false show_source: false + members: + - __init__ + - process_webhook + - send_response + +## ChatChannel ::: tac.channels.chat.ChatChannel options: - show_root_heading: true + show_root_heading: false show_source: false + members: + - __init__ + - process_webhook + - send_response diff --git a/docs/api/core.md b/docs/api/core.md index 1f6b248..c03992f 100644 --- a/docs/api/core.md +++ b/docs/api/core.md @@ -1,13 +1,27 @@ # Core API Reference +## TAC + ::: tac.TAC options: - show_root_heading: true + show_root_heading: false show_source: false - members_order: source + members: + - __init__ + - on_message_ready + - on_conversation_ended + - retrieve_memory + - is_orchestrator_enabled + +## TACConfig ::: tac.TACConfig options: - show_root_heading: true + show_root_heading: false show_source: false - members_order: source + members: + - from_env + - account_sid + - api_key + - api_secret + - conversation_configuration_id diff --git a/docs/api/server.md b/docs/api/server.md index 0387d9c..a84fc3f 100644 --- a/docs/api/server.md +++ b/docs/api/server.md @@ -1,6 +1,12 @@ # Server API Reference +## TACFastAPIServer + ::: tac.server.TACFastAPIServer options: - show_root_heading: true + show_root_heading: false show_source: false + members: + - __init__ + - start + - get_app diff --git a/mkdocs.yml b/mkdocs.yml index f4f34b4..67bc96d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -43,11 +43,15 @@ plugins: paths: [src] options: docstring_style: google - show_source: true + show_source: false show_root_heading: true show_symbol_type_heading: true show_symbol_type_toc: true members_order: source + filters: + - "!^_" # Exclude private members (starting with _) + - "!^model_" # Exclude Pydantic internal methods + show_if_no_docstring: false # Hide undocumented members markdown_extensions: - pymdownx.highlight: From fe4a6346b38914a533493e7b7254ceaf4686c5bd Mon Sep 17 00:00:00 2001 From: jahuang Date: Mon, 18 May 2026 13:30:38 -0700 Subject: [PATCH 5/7] Switch to fully auto-generated API documentation - Simplify all API doc files to use module-level auto-generation - Remove manual member lists - now controlled by __all__ in Python code - Add DOCS_CONTROL.md guide explaining how to control docs from code - Docs now auto-generated from __all__ exports + docstrings - To hide: use _ prefix or remove from __all__ - To show: add to __all__ and add docstring --- DOCS_CONTROL.md | 166 +++++++++++++++++++++++++++++++++++++++++++ docs/api/adapters.md | 6 +- docs/api/channels.md | 53 +------------- docs/api/core.md | 23 +----- docs/api/server.md | 8 +-- 5 files changed, 170 insertions(+), 86 deletions(-) create mode 100644 DOCS_CONTROL.md diff --git a/DOCS_CONTROL.md b/DOCS_CONTROL.md new file mode 100644 index 0000000..daaffc9 --- /dev/null +++ b/DOCS_CONTROL.md @@ -0,0 +1,166 @@ +# Controlling Auto-Generated Documentation + +API documentation is automatically generated from Python source code using mkdocstrings. This guide explains how to control what appears in the docs. + +## Quick Reference + +**To hide something from docs:** +- Add `_` prefix to method/function name (e.g., `_internal_method`) +- Remove from `__all__` list in module's `__init__.py` +- Don't add a docstring (filtered automatically) + +**To show something in docs:** +- Add to `__all__` list in module's `__init__.py` +- Make it public (no `_` prefix) +- Add a docstring + +## Method 1: Control with __all__ (Module Level) + +The `__all__` list in each module's `__init__.py` controls which classes/functions appear in docs. + +### Example: Hide a class from channels + +```python +# src/tac/channels/__init__.py +__all__ = [ + "VoiceChannel", + "SMSChannel", + # "RCSChannel", ← Comment out to hide from docs + "WhatsAppChannel", + "ChatChannel", +] +``` + +### Files to Edit: + +| Module | File | Controls | +|--------|------|----------| +| Core | `src/tac/core/__init__.py` | TAC, TACConfig, get_logger | +| Channels | `src/tac/channels/__init__.py` | VoiceChannel, SMSChannel, etc. | +| Adapters | `src/tac/adapters/__init__.py` | with_tac_memory | +| Server | `src/tac/server/__init__.py` | TACFastAPIServer | +| Models | `src/tac/models/__init__.py` | TwiMLOptions, etc. | + +## Method 2: Use Underscore Prefix (Method Level) + +Methods/functions starting with `_` are considered private and hidden from docs. + +```python +class TAC: + def on_message_ready(self): + """Public method - shows in docs.""" + pass + + def _internal_helper(self): + """Private method - hidden from docs.""" + pass +``` + +### Example: Hide is_orchestrator_enabled + +**Before:** +```python +def is_orchestrator_enabled(self) -> bool: + """Check if orchestrator is enabled.""" +``` + +**After:** +```python +def _is_orchestrator_enabled(self) -> bool: + """Internal: Check if orchestrator is enabled.""" +``` + +## Method 3: Remove Docstring + +Methods without docstrings are automatically hidden (configured in `mkdocs.yml`). + +```python +def internal_method(self): + # No docstring = hidden from docs + pass +``` + +## Current Filters (mkdocs.yml) + +These filters are already configured: + +```yaml +filters: + - "!^_" # Hide _private methods + - "!^model_" # Hide Pydantic internals (model_dump, model_config, etc.) +show_if_no_docstring: false # Hide undocumented members +``` + +## Typical Workflow + +### 1. Adding a new public class + +```python +# src/tac/channels/email.py +class EmailChannel: + """Send messages via email.""" + + def __init__(self, tac): + """Initialize email channel.""" + self.tac = tac +``` + +```python +# src/tac/channels/__init__.py +__all__ = [ + "VoiceChannel", + "SMSChannel", + "EmailChannel", # ← Add here to show in docs +] +``` + +### 2. Hiding an internal method + +Just add `_` prefix - no other changes needed: + +```python +class TAC: + def retrieve_memory(self): + """Public API - shows in docs.""" + return self._fetch_from_api() + + def _fetch_from_api(self): + """Internal implementation - hidden.""" + pass +``` + +### 3. Marking something as experimental + +Keep it public but note in docstring: + +```python +def new_feature(self): + """Experimental feature. + + Warning: + This API is experimental and may change in future versions. + """ +``` + +## Rebuilding Docs + +After changing `__all__` or method names: + +```bash +# Local preview +uv run mkdocs serve + +# Build for deployment +uv run mkdocs build +``` + +Changes are automatically picked up when you push to the `main` branch (via GitHub Actions). + +## Summary + +**Most common controls:** +1. **Hide class:** Remove from `__all__` in `__init__.py` +2. **Hide method:** Add `_` prefix +3. **Hide undocumented:** Don't add docstring (automatic) + +**All control happens in Python source code** - no need to maintain separate doc files! diff --git a/docs/api/adapters.md b/docs/api/adapters.md index 2d45e34..81334f9 100644 --- a/docs/api/adapters.md +++ b/docs/api/adapters.md @@ -1,10 +1,6 @@ # Adapters API Reference -## OpenAI Adapter - -### with_tac_memory - -::: tac.adapters.openai.adapter.with_tac_memory +::: tac.adapters options: show_root_heading: false show_source: false diff --git a/docs/api/channels.md b/docs/api/channels.md index d930753..5392702 100644 --- a/docs/api/channels.md +++ b/docs/api/channels.md @@ -1,57 +1,6 @@ # Channels API Reference -## VoiceChannel - -::: tac.channels.voice.VoiceChannel - options: - show_root_heading: false - show_source: false - members: - - __init__ - - handle_incoming_call - - handle_websocket - - send_response - -## SMSChannel - -::: tac.channels.sms.SMSChannel - options: - show_root_heading: false - show_source: false - members: - - __init__ - - process_webhook - - send_response - -## RCSChannel - -::: tac.channels.rcs.RCSChannel - options: - show_root_heading: false - show_source: false - members: - - __init__ - - process_webhook - - send_response - -## WhatsAppChannel - -::: tac.channels.whatsapp.WhatsAppChannel - options: - show_root_heading: false - show_source: false - members: - - __init__ - - process_webhook - - send_response - -## ChatChannel - -::: tac.channels.chat.ChatChannel +::: tac.channels options: show_root_heading: false show_source: false - members: - - __init__ - - process_webhook - - send_response diff --git a/docs/api/core.md b/docs/api/core.md index c03992f..9b311dd 100644 --- a/docs/api/core.md +++ b/docs/api/core.md @@ -1,27 +1,6 @@ # Core API Reference -## TAC - -::: tac.TAC - options: - show_root_heading: false - show_source: false - members: - - __init__ - - on_message_ready - - on_conversation_ended - - retrieve_memory - - is_orchestrator_enabled - -## TACConfig - -::: tac.TACConfig +::: tac.core options: show_root_heading: false show_source: false - members: - - from_env - - account_sid - - api_key - - api_secret - - conversation_configuration_id diff --git a/docs/api/server.md b/docs/api/server.md index a84fc3f..3bb8035 100644 --- a/docs/api/server.md +++ b/docs/api/server.md @@ -1,12 +1,6 @@ # Server API Reference -## TACFastAPIServer - -::: tac.server.TACFastAPIServer +::: tac.server options: show_root_heading: false show_source: false - members: - - __init__ - - start - - get_app From d0b691857d7f214c8e07110c80d0485746d6990b Mon Sep 17 00:00:00 2001 From: jahuang Date: Mon, 18 May 2026 13:33:14 -0700 Subject: [PATCH 6/7] Simplify to single API reference page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Consolidate all API docs into single docs/api.md file - Remove docs/api/ folder (5 files → 1 file) - Update navigation to single 'API Reference' entry - All sections (Core, Channels, Adapters, Server, Models) on one page - Zero maintenance - fully auto-generated from __all__ --- docs/api.md | 36 ++++++++++++++++++++++++++++++++++++ docs/api/adapters.md | 6 ------ docs/api/channels.md | 6 ------ docs/api/core.md | 6 ------ docs/api/models.md | 10 ---------- docs/api/server.md | 6 ------ mkdocs.yml | 7 +------ 7 files changed, 37 insertions(+), 40 deletions(-) create mode 100644 docs/api.md delete mode 100644 docs/api/adapters.md delete mode 100644 docs/api/channels.md delete mode 100644 docs/api/core.md delete mode 100644 docs/api/models.md delete mode 100644 docs/api/server.md diff --git a/docs/api.md b/docs/api.md new file mode 100644 index 0000000..1016edd --- /dev/null +++ b/docs/api.md @@ -0,0 +1,36 @@ +# API Reference + +## Core + +::: tac.core + options: + show_root_heading: false + show_source: false + +## Channels + +::: tac.channels + options: + show_root_heading: false + show_source: false + +## Adapters + +::: tac.adapters + options: + show_root_heading: false + show_source: false + +## Server + +::: tac.server + options: + show_root_heading: false + show_source: false + +## Models + +::: tac.models + options: + show_root_heading: false + show_source: false diff --git a/docs/api/adapters.md b/docs/api/adapters.md deleted file mode 100644 index 81334f9..0000000 --- a/docs/api/adapters.md +++ /dev/null @@ -1,6 +0,0 @@ -# Adapters API Reference - -::: tac.adapters - options: - show_root_heading: false - show_source: false diff --git a/docs/api/channels.md b/docs/api/channels.md deleted file mode 100644 index 5392702..0000000 --- a/docs/api/channels.md +++ /dev/null @@ -1,6 +0,0 @@ -# Channels API Reference - -::: tac.channels - options: - show_root_heading: false - show_source: false diff --git a/docs/api/core.md b/docs/api/core.md deleted file mode 100644 index 9b311dd..0000000 --- a/docs/api/core.md +++ /dev/null @@ -1,6 +0,0 @@ -# Core API Reference - -::: tac.core - options: - show_root_heading: false - show_source: false diff --git a/docs/api/models.md b/docs/api/models.md deleted file mode 100644 index 4e85930..0000000 --- a/docs/api/models.md +++ /dev/null @@ -1,10 +0,0 @@ -# Models API Reference - -API data models used throughout TAC. - -::: tac.models - options: - show_root_heading: false - show_source: false - members_order: source - group_by_category: true diff --git a/docs/api/server.md b/docs/api/server.md deleted file mode 100644 index 3bb8035..0000000 --- a/docs/api/server.md +++ /dev/null @@ -1,6 +0,0 @@ -# Server API Reference - -::: tac.server - options: - show_root_heading: false - show_source: false diff --git a/mkdocs.yml b/mkdocs.yml index 67bc96d..6f1560d 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -75,12 +75,7 @@ markdown_extensions: nav: - Home: index.md - - API Reference: - - Core: api/core.md - - Channels: api/channels.md - - Models: api/models.md - - Adapters: api/adapters.md - - Server: api/server.md + - API Reference: api.md extra: social: From 1b437dbd0be2d181ccf4632ff3f0ecfdc0db9a3c Mon Sep 17 00:00:00 2001 From: jahuang Date: Mon, 18 May 2026 13:43:58 -0700 Subject: [PATCH 7/7] Simplify documentation setup to minimal configuration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use README.md as home page (symlink docs/index.md → README.md) - Keep only docs/api.md for API reference - Simplify mkdocs.yml to bare minimum (removed theme customization, markdown extensions) - Single source of truth: README.md maintained in root - Zero maintenance: Home = README.md (symlink), API = auto-generated from __all__ --- docs/index.md | 128 +------------------------------------------------- mkdocs.yml | 70 ++------------------------- 2 files changed, 4 insertions(+), 194 deletions(-) mode change 100644 => 120000 docs/index.md diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 7329457..0000000 --- a/docs/index.md +++ /dev/null @@ -1,127 +0,0 @@ -# Twilio Agent Connect Python SDK - -
- TAC Logo -
- -A powerful SDK for building intelligent, context-aware AI agents with Twilio's communication technologies. - -[![Python SDK](https://img.shields.io/badge/Python-3.10+-3776AB.svg)](https://github.com/twilio/twilio-agent-connect-python) -[![PyPI](https://img.shields.io/pypi/v/twilio-agent-connect.svg)](https://pypi.org/project/twilio-agent-connect/) -[![CI](https://github.com/twilio/twilio-agent-connect-python/actions/workflows/ci.yml/badge.svg)](https://github.com/twilio/twilio-agent-connect-python/actions/workflows/ci.yml) -[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://github.com/twilio/twilio-agent-connect-python/blob/main/LICENSE) - ---- - -## Overview - -Seamlessly integrate with Twilio Conversation Memory and Conversation Orchestrator to build LLM-powered agents with persistent memory and conversation context. - -!!! tip "Building AI agents on AWS or Microsoft?" - Connect them to Twilio's voice, messaging, and conversation context with these dedicated packages: - - - **[TAC for AWS](https://github.com/twilio/twilio-agent-connect-aws)** — Strands, Bedrock Agents, Bedrock AgentCore - - **[TAC for Microsoft](https://github.com/twilio/twilio-agent-connect-microsoft)** — Microsoft Agent Framework, Azure AI Foundry (incl. Voice Live), Azure OpenAI - -## Key Features - -- **Multi-Channel Support**: Built-in handling for Voice (ConversationRelay), SMS, RCS, WhatsApp, and Chat -- **Outbound Conversations**: Agent-initiated conversations across all supported channels -- **ConversationRelay-Only Mode**: Get started quickly with TAC's voice plumbing (TwiML, WebSocket, callbacks) before adding Conversation Orchestrator or Conversation Memory -- **Memory Management**: Automatic integration with Twilio Conversation Memory for persistent user context -- **Conversation Lifecycle**: Automatic tracking of conversation sessions and state -- **Human Handoff**: Built-in tool to route conversations to human agents via Twilio Studio Flows (including Flex) - -## Installation - -=== "Basic Installation" - ```bash - pip install twilio-agent-connect - ``` - -=== "With Server Support" - ```bash - pip install "twilio-agent-connect[server]" - ``` - -!!! note "Requirements" - TAC requires **Python 3.10 or newer**. - -## Quick Start - -Here's a minimal example to get you started: - -```python -from dotenv import load_dotenv -from openai import AsyncOpenAI -from tac import TAC, TACConfig -from tac.adapters.openai import with_tac_memory -from tac.channels.sms import SMSChannel -from tac.channels.voice import VoiceChannel -from tac.server import TACFastAPIServer - -load_dotenv() - -tac = TAC(config=TACConfig.from_env()) -voice_channel = VoiceChannel(tac) -sms_channel = SMSChannel(tac) -openai_client = AsyncOpenAI() - -conversation_history = {} -SYSTEM_INSTRUCTIONS = ( - "You are a customer service agent speaking with a user over voice or SMS. " - "Keep responses short and conversational — a sentence or two. " - "Do not use markdown, asterisks, bullets, or emojis; your words will be " - "spoken aloud or sent as plain text." -) - -async def handle_message_ready(user_message, context, memory_response): - conv_id = context.conversation_id - - if conv_id not in conversation_history: - conversation_history[conv_id] = [] - conversation_history[conv_id].append({"role": "user", "content": user_message}) - - client = with_tac_memory(openai_client, memory_response, context) - - response = await client.responses.create( - model="gpt-5.4-mini", - instructions=SYSTEM_INSTRUCTIONS, - input=conversation_history[conv_id] - ) - - llm_response = response.output_text - conversation_history[conv_id].append({"role": "assistant", "content": llm_response}) - - return llm_response - -tac.on_message_ready(handle_message_ready) -TACFastAPIServer(tac=tac, voice_channel=voice_channel, messaging_channels=[sms_channel]).start() -``` - -**That's it!** The server automatically: - -- Creates FastAPI app with `/twiml`, `/ws`, and `/webhook` endpoints -- Handles Voice, SMS, RCS, WhatsApp, and Chat conversations -- Routes responses to the appropriate channel -- Injects conversation memory and user profile into OpenAI calls - -For detailed setup instructions, see the [GitHub README](https://github.com/twilio/twilio-agent-connect-python). - -## API Reference - -Explore the complete API documentation: - -- [Core API](api/core.md) - TAC, TACConfig, context models -- [Channels](api/channels.md) - Voice, SMS, RCS, WhatsApp, Chat -- [Models](api/models.md) - Data models for conversations, memory, sessions -- [Adapters](api/adapters.md) - OpenAI integration -- [Server](api/server.md) - FastAPI server setup - -## Learn More - -- **[GitHub Repository](https://github.com/twilio/twilio-agent-connect-python)** - Source code and examples -- **[Official Documentation](https://www.twilio.com/docs/conversations/agent-connect)** - Twilio's official docs -- **[PyPI Package](https://pypi.org/project/twilio-agent-connect/)** - Package registry -- **[TAC for AWS](https://github.com/twilio/twilio-agent-connect-aws)** - AWS integrations -- **[TAC for Microsoft](https://github.com/twilio/twilio-agent-connect-microsoft)** - Microsoft integrations diff --git a/docs/index.md b/docs/index.md new file mode 120000 index 0000000..32d46ee --- /dev/null +++ b/docs/index.md @@ -0,0 +1 @@ +../README.md \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 6f1560d..c1da062 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,39 +1,9 @@ site_name: Twilio Agent Connect Python SDK -site_description: A powerful SDK for building intelligent, context-aware AI agents with Twilio's communication technologies site_url: https://twilio.github.io/twilio-agent-connect-python/ repo_url: https://github.com/twilio/twilio-agent-connect-python -repo_name: twilio/twilio-agent-connect-python -edit_uri: edit/main/docs/ theme: name: material - palette: - # Light mode - - scheme: default - primary: red - accent: red - toggle: - icon: material/brightness-7 - name: Switch to dark mode - # Dark mode - - scheme: slate - primary: red - accent: red - toggle: - icon: material/brightness-4 - name: Switch to light mode - features: - - navigation.tabs - - navigation.sections - - navigation.expand - - navigation.top - - search.suggest - - search.highlight - - content.tabs.link - - content.code.annotation - - content.code.copy - logo: https://raw.githubusercontent.com/twilio/twilio-agent-connect-python/main/logo.svg - favicon: https://raw.githubusercontent.com/twilio/twilio-agent-connect-python/main/logo.svg plugins: - search @@ -42,46 +12,12 @@ plugins: python: paths: [src] options: - docstring_style: google show_source: false - show_root_heading: true - show_symbol_type_heading: true - show_symbol_type_toc: true - members_order: source filters: - - "!^_" # Exclude private members (starting with _) - - "!^model_" # Exclude Pydantic internal methods - show_if_no_docstring: false # Hide undocumented members - -markdown_extensions: - - pymdownx.highlight: - anchor_linenums: true - line_spans: __span - pygments_lang_class: true - - pymdownx.inlinehilite - - pymdownx.snippets - - pymdownx.superfences - - pymdownx.tabbed: - alternate_style: true - - admonition - - pymdownx.details - - pymdownx.emoji: - emoji_index: !!python/name:material.extensions.emoji.twemoji - emoji_generator: !!python/name:material.extensions.emoji.to_svg - - attr_list - - md_in_html - - toc: - permalink: true + - "!^_" + - "!^model_" + show_if_no_docstring: false nav: - Home: index.md - API Reference: api.md - -extra: - social: - - icon: fontawesome/brands/github - link: https://github.com/twilio/twilio-agent-connect-python - - icon: fontawesome/brands/python - link: https://pypi.org/project/twilio-agent-connect/ - version: - provider: mike