Serverless

View as MarkdownOpen in Claude

Serverless Deployment

Deploy agents to AWS Lambda, Google Cloud Functions, or Azure Functions. The SDK automatically detects serverless environments and adapts accordingly.

Serverless Overview

PlatformRuntimeEntry PointMax TimeoutFree Tier
AWS LambdaPython 3.11lambda_handler15 min1M requests/mo
Google Cloud FunctionsPython 3.11main60 min (Gen 2)2M invocations/mo
Azure FunctionsPython 3.11main10 min (Consumption)1M executions/mo

Benefits:

  • Auto-scaling
  • Pay per invocation
  • No server management
  • High availability

AWS Lambda

Lambda Handler

handler.py:

1from signalwire_agents import AgentBase, SwaigFunctionResult
2
3
4class MyAgent(AgentBase):
5 def __init__(self):
6 super().__init__(name="my-agent")
7 self.add_language("English", "en-US", "rime.spore")
8 self.prompt_add_section("Role", "You are a helpful assistant.")
9 self._setup_functions()
10
11 def _setup_functions(self):
12 @self.tool(
13 description="Say hello to a user",
14 parameters={
15 "type": "object",
16 "properties": {
17 "name": {
18 "type": "string",
19 "description": "Name of the person to greet"
20 }
21 },
22 "required": ["name"]
23 }
24 )
25 def say_hello(args, raw_data):
26 name = args.get("name", "World")
27 return SwaigFunctionResult(f"Hello {name}!")
28
29
30# Create agent instance outside handler for warm starts
31agent = MyAgent()
32
33
34def lambda_handler(event, context):
35 """AWS Lambda entry point."""
36 return agent.run(event, context)

Lambda requirements.txt

signalwire-agents>=1.0.15

Lambda with API Gateway (Serverless Framework)

1## serverless.yml
2service: signalwire-agent
3
4provider:
5 name: aws
6 runtime: python3.11
7 region: us-east-1
8 environment:
9 SWML_BASIC_AUTH_USER: ${env:SWML_BASIC_AUTH_USER}
10 SWML_BASIC_AUTH_PASSWORD: ${env:SWML_BASIC_AUTH_PASSWORD}
11
12functions:
13 agent:
14 handler: handler.lambda_handler
15 events:
16 - http:
17 path: /
18 method: any
19 - http:
20 path: /{proxy+}
21 method: any

Lambda Request Flow

Lambda Request Flow.
Lambda Request Flow

Google Cloud Functions

Cloud Functions Handler

main.py:

1from signalwire_agents import AgentBase, SwaigFunctionResult
2
3
4class MyAgent(AgentBase):
5 def __init__(self):
6 super().__init__(name="my-agent")
7 self.add_language("English", "en-US", "rime.spore")
8 self.prompt_add_section("Role", "You are a helpful assistant.")
9 self._setup_functions()
10
11 def _setup_functions(self):
12 @self.tool(
13 description="Say hello to a user",
14 parameters={
15 "type": "object",
16 "properties": {
17 "name": {
18 "type": "string",
19 "description": "Name of the person to greet"
20 }
21 },
22 "required": ["name"]
23 }
24 )
25 def say_hello(args, raw_data):
26 name = args.get("name", "World")
27 return SwaigFunctionResult(f"Hello {name}!")
28
29
30# Create agent instance outside handler for warm starts
31agent = MyAgent()
32
33
34def main(request):
35 """Google Cloud Functions entry point."""
36 return agent.run(request)

Cloud Functions requirements.txt

signalwire-agents>=1.0.15
functions-framework>=3.0.0

Deploying to Cloud Functions (Gen 2)

$gcloud functions deploy signalwire-agent \
> --gen2 \
> --runtime python311 \
> --trigger-http \
> --allow-unauthenticated \
> --entry-point main \
> --region us-central1 \
> --set-env-vars SWML_BASIC_AUTH_USER=user,SWML_BASIC_AUTH_PASSWORD=pass

Azure Functions

Azure Functions Handler

function_app/__init__.py:

1import azure.functions as func
2from signalwire_agents import AgentBase, SwaigFunctionResult
3
4
5class MyAgent(AgentBase):
6 def __init__(self):
7 super().__init__(name="my-agent")
8 self.add_language("English", "en-US", "rime.spore")
9 self.prompt_add_section("Role", "You are a helpful assistant.")
10 self._setup_functions()
11
12 def _setup_functions(self):
13 @self.tool(
14 description="Say hello to a user",
15 parameters={
16 "type": "object",
17 "properties": {
18 "name": {
19 "type": "string",
20 "description": "Name of the person to greet"
21 }
22 },
23 "required": ["name"]
24 }
25 )
26 def say_hello(args, raw_data):
27 name = args.get("name", "World")
28 return SwaigFunctionResult(f"Hello {name}!")
29
30
31# Create agent instance outside handler for warm starts
32agent = MyAgent()
33
34
35def main(req: func.HttpRequest) -> func.HttpResponse:
36 """Azure Functions entry point."""
37 return agent.run(req)

Azure Functions requirements.txt

azure-functions>=1.17.0
signalwire-agents>=1.0.15

function.json

1{
2 "scriptFile": "__init__.py",
3 "bindings": [
4 {
5 "authLevel": "anonymous",
6 "type": "httpTrigger",
7 "direction": "in",
8 "name": "req",
9 "methods": ["get", "post"],
10 "route": "{*path}"
11 },
12 {
13 "type": "http",
14 "direction": "out",
15 "name": "$return"
16 }
17 ]
18}

host.json

1{
2 "version": "2.0",
3 "extensionBundle": {
4 "id": "Microsoft.Azure.Functions.ExtensionBundle",
5 "version": "[4.*, 5.0.0)"
6 }
7}

Testing Serverless

Local Testing with swaig-test

$## Simulate AWS Lambda
$swaig-test handler.py --simulate-serverless lambda --dump-swml
$
$## Simulate Google Cloud Functions
$swaig-test main.py --simulate-serverless cloud_function --dump-swml
$
$## Simulate Azure Functions
$swaig-test function_app/__init__.py --simulate-serverless azure_function --dump-swml

Testing Deployed Endpoints

$## Test SWML output (replace with your endpoint and credentials)
$curl -u username:password https://your-endpoint/
$
$## Test SWAIG function
$curl -u username:password -X POST https://your-endpoint/swaig \
> -H 'Content-Type: application/json' \
> -d '{"function": "say_hello", "argument": {"parsed": [{"name": "Alice"}]}}'

Authentication

The SDK automatically enables HTTP Basic Authentication. You can:

  1. Let the SDK generate credentials - Secure random credentials are created automatically
  2. Set your own credentials - Via environment variables:
$export SWML_BASIC_AUTH_USER=myuser
$export SWML_BASIC_AUTH_PASSWORD=mypassword

Force Mode Override

For testing, you can force a specific execution mode:

1## Force Lambda mode
2agent.run(event={}, context=None, force_mode='lambda')
3
4## Force Cloud Functions mode
5agent.run(request, force_mode='google_cloud_function')
6
7## Force Azure mode
8agent.run(req, force_mode='azure_function')

Serverless Best Practices

Cold Starts

  • Keep dependencies minimal
  • Initialize agent outside handler function
  • Use provisioned concurrency for low latency

Timeouts

  • Set appropriate timeout (Lambda: up to 15 min)
  • Account for external API calls
  • Monitor and optimize slow functions

Memory

  • Allocate sufficient memory
  • More memory = more CPU in Lambda
  • Monitor memory usage

State

  • Design for statelessness
  • Use external storage for persistent data
  • Don’t rely on local filesystem

Multi-Agent Serverless

Deploy multiple agents with AgentServer:

1from signalwire_agents import AgentBase, AgentServer
2
3
4class SalesAgent(AgentBase):
5 def __init__(self):
6 super().__init__(name="sales-agent")
7 self.add_language("English", "en-US", "rime.spore")
8
9
10class SupportAgent(AgentBase):
11 def __init__(self):
12 super().__init__(name="support-agent")
13 self.add_language("English", "en-US", "rime.spore")
14
15
16server = AgentServer()
17server.register(SalesAgent(), "/sales")
18server.register(SupportAgent(), "/support")
19
20
21def lambda_handler(event, context):
22 """Lambda handler for multi-agent server"""
23 return server.run(event, context)

Environment Detection

The SDK detects serverless environments automatically:

Environment VariablePlatform
AWS_LAMBDA_FUNCTION_NAMEAWS Lambda
LAMBDA_TASK_ROOTAWS Lambda
FUNCTION_TARGETGoogle Cloud Functions
K_SERVICEGoogle Cloud Functions
GOOGLE_CLOUD_PROJECTGoogle Cloud Functions
AZURE_FUNCTIONS_ENVIRONMENTAzure Functions
FUNCTIONS_WORKER_RUNTIMEAzure Functions