Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

234 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

SignalWire SDK for Perl

Build AI voice agents, control live calls over WebSocket, and manage every SignalWire resource over REST -- all from one package.

Documentation · Report an Issue · CPAN

Discord MIT License GitHub Stars

Open in GitHub Codespaces Run on Replit


What's in this SDK

Capability What it does Quick link
AI Agents Build voice agents that handle calls autonomously -- the platform runs the AI pipeline, your code defines the persona, tools, and call flow Agent Guide
RELAY Client Control live calls and SMS/MMS in real time over WebSocket -- answer, play, record, collect DTMF, conference, transfer, and more RELAY docs
REST Client Manage SignalWire resources over HTTP -- phone numbers, SIP endpoints, Fabric AI agents, video rooms, messaging, and 22 API namespaces REST docs
cpanm SignalWire

Version note: until the next CPAN cut lands, cpanm SignalWire may resolve an older published release. To track the code in this repository, install from source (see Installation). You will need SignalWire API credentials (Project ID + API token) from your SignalWire Dashboard — see Environment variables.


AI Agents

Each agent is a self-contained microservice that generates SWML (SignalWire Markup Language) and handles SWAIG (SignalWire AI Gateway) tool calls. The SignalWire platform runs the entire AI pipeline (STT, LLM, TTS) -- your agent just defines the behavior.

use strict;
use warnings;
use SignalWire;
use SignalWire::Agent::AgentBase;
use SignalWire::SWAIG::FunctionResult;
use POSIX qw(strftime);

my $agent = SignalWire::Agent::AgentBase->new(
    name  => 'my-agent',
    route => '/agent',
);

$agent->add_language( name => 'English', code => 'en-US', voice => 'inworld.Mark' );
$agent->prompt_add_section( 'Role', 'You are a helpful assistant.' );

$agent->define_tool(
    name        => 'get_time',
    description => 'Get the current time',
    parameters  => {},
    handler     => sub {
        my ( $args, $raw_data ) = @_;
        return SignalWire::SWAIG::FunctionResult->new(
            response => 'The time is ' . strftime( '%H:%M:%S', localtime ) );
    },
);

$agent->run;

Test locally without running a server:

swaig-test --file my_agent.pl --list-tools
swaig-test --file my_agent.pl --dump-swml
swaig-test --file my_agent.pl --exec get_time

In-process agent-file contract (guard + return the agent). swaig-test --file loads your script with do to introspect its tools/SWML, so the script must yield the built agent and must not block on a server. Two things make this automatic:

  • Return the agent as the file's last value. End your script with the agent object ($agent;) — or define a build_service sub (your own, in the script) that returns one, or a package that extends SignalWire::Agent::AgentBase. swaig-test resolves any of these.
  • $agent->run is safe to leave in. When swaig-test loads the file it sets SWAIG_TEST_INPROCESS=1; under that flag run()/serve() no-op and return the agent instead of binding a socket. So the same $agent->run; that serves in production is harmless under the test harness — you do not need a hand-written unless caller guard. (The quickstart above ends in $agent->run; and works with swaig-test --file unchanged.)

Agent Features

  • Prompt Object Model (POM) -- structured prompt composition via prompt_add_section()
  • SWAIG tools -- define functions with define_tool() that the AI calls mid-conversation, with native access to the call's media stack
  • Skills system -- add capabilities with one-liners: $agent->add_skill('datetime')
  • Contexts and steps -- structured multi-step workflows with navigation control
  • DataMap tools -- tools that execute on SignalWire's servers, calling REST APIs without your own webhook
  • Dynamic configuration -- per-request agent customization for multi-tenant deployments
  • Call flow control -- pre-answer, post-answer, and post-AI verb insertion
  • Prefab agents -- ready-to-use archetypes (InfoGatherer, Survey, FAQ, Receptionist, Concierge)
  • Multi-agent hosting -- serve multiple agents on a single server with SignalWire::Server::AgentServer
  • SIP routing -- route SIP calls to agents based on usernames
  • Session state -- persistent conversation state with global data and post-prompt summaries
  • Security -- auto-generated basic auth, function-specific HMAC tokens, SSL support
  • Serverless -- auto-detects Lambda, CGI, Google Cloud Functions, Azure Functions
  • PSGI/Plack -- run standalone or mount in any PSGI-compatible framework

Agent Examples

The examples/ directory contains 50+ working examples:

Example What it demonstrates
simple_agent.pl POM prompts, SWAIG tools, multilingual support, LLM tuning
contexts_demo.pl Multi-persona workflow with context switching and step navigation
datamap_demo.pl Server-side API tools without webhooks
skills_demo.pl Loading built-in skills (datetime, math)
call_flow_and_actions_demo.pl Call flow verbs, debug events, FunctionResult actions
session_and_state_demo.pl on_summary, global data, post-prompt summaries
multi_agent_server.pl Multiple agents on one server
lambda_agent.pl AWS Lambda deployment
comprehensive_dynamic.pl Per-request dynamic configuration, multi-tenant routing

See examples/README.md for the full list organized by category.


RELAY Client

Real-time call control and messaging over WebSocket. The RELAY client connects to SignalWire via the Blade protocol and gives you imperative control over live phone calls and SMS/MMS.

use strict;
use warnings;
use SignalWire::Relay::Client;

my $client = SignalWire::Relay::Client->new(
    project  => $ENV{SIGNALWIRE_PROJECT_ID},
    token    => $ENV{SIGNALWIRE_API_TOKEN},
    host     => $ENV{SIGNALWIRE_SPACE} // 'relay.signalwire.com',
    contexts => ['default'],
);

$client->on_call(
    sub {
        my ($call) = @_;
        $call->answer;
        my $action =
            $call->play( play => [ { type => 'tts', params => { text => 'Welcome!' } } ] );
        $action->wait;
        $call->hangup;
    }
);

$client->connect_ws or die "Connection failed\n";
$client->authenticate;
$client->run;
  • 57+ calling methods (play, record, collect, detect, tap, stream, AI, conferencing, and more)
  • SMS/MMS messaging with delivery tracking
  • Action objects with wait(), stop(), pause(), resume()
  • Auto-reconnect with exponential backoff

See the RELAY documentation for the full guide, API reference, and examples.


REST Client

Synchronous REST client for managing SignalWire resources and controlling calls over HTTP. No WebSocket required.

use strict;
use warnings;
use SignalWire::REST::RestClient;

my $client = SignalWire::REST::RestClient->new(
    project => $ENV{SIGNALWIRE_PROJECT_ID},
    token   => $ENV{SIGNALWIRE_API_TOKEN},
    host    => $ENV{SIGNALWIRE_SPACE},
);

$client->fabric->ai_agents->create(
    name   => 'Support Bot',
    prompt => { text => 'You are helpful.' }
);

my $call_id = 'call-id-from-a-prior-request';
$client->calling->play( $call_id, play => [ { type => 'tts', params => { text => 'Hello!' } } ] );
$client->phone_numbers->search( areacode => '512' );
$client->datasphere->documents->search( query_string => 'billing policy' );
  • 22 namespaced API surfaces: Fabric (16 resource types), Calling (40 commands), Video, Datasphere, Phone Numbers, SIP, Queues, Recordings, and more
  • HTTP::Tiny for lightweight, dependency-free HTTP
  • Hash ref returns -- raw data, no wrapper objects

See the REST documentation for the full guide, API reference, and examples.


Installation

Requires Perl 5.36+.

# From CPAN (may resolve an older published release until the next cut)
cpanm SignalWire

# From source (tracks this repository — recommended for the latest code)
git clone https://github.com/signalwire/signalwire-perl.git
cd signalwire-perl
cpanm --installdeps .
perl Makefile.PL
make test
make install

Documentation

Full reference documentation is available at developer.signalwire.com/sdks/agents-sdk.

Guides are also available in the docs/ directory:

Getting Started

  • Agent Guide -- creating agents, prompt configuration, dynamic setup
  • Architecture -- SDK architecture and core concepts
  • SDK Features -- feature overview, SDK vs raw SWML comparison

Core Features

Skills and Extensions

Deployment

Reference

Environment Variables

Variable Used by Description
SIGNALWIRE_PROJECT_ID RELAY, REST Project identifier
SIGNALWIRE_API_TOKEN RELAY, REST API token
SIGNALWIRE_SPACE RELAY, REST Space hostname (e.g. example.signalwire.com)
SWML_BASIC_AUTH_USER Agents Basic auth username (default: auto-generated)
SWML_BASIC_AUTH_PASSWORD Agents Basic auth password (default: auto-generated)
SWML_PROXY_URL_BASE Agents Base URL when behind a reverse proxy
SWML_SSL_ENABLED Agents Enable HTTPS (true, 1, yes)
SWML_SSL_CERT_PATH Agents Path to SSL certificate
SWML_SSL_KEY_PATH Agents Path to SSL private key
SIGNALWIRE_LOG_LEVEL All Logging level (debug, info, warn, error)
SIGNALWIRE_LOG_MODE All Set to off to suppress all logging

Testing, linting, and formatting

Three canonical scripts under scripts/ are the single entry point for testing, linting, and formatting. Each self-bootstraps its tool environment (perltidy, perlcritic, and the local::lib runtime deps) and runs from any directory — no PERL5LIB / PATH setup required from the caller.

# Install dependencies (first time only)
cpanm --with-develop --installdeps .

# Run the full test suite
bash scripts/run-tests.sh

# Run a subset (any prove target passes straight through)
bash scripts/run-tests.sh t/06_agent.t

# Lint (perlcritic severity 4, zero findings)
bash scripts/run-lint.sh

# Format the tree in place (perltidy)
bash scripts/run-format.sh
# ...or verify-only, no writes (the CI FMT gate)
bash scripts/run-format.sh --check

All of the above also run as gates inside bash scripts/run-ci.sh.

License

MIT -- see LICENSE for details.

About

SignalWire AI Agents Perl SDK, Relay and REST

Resources

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages