concinno-skills-mobile
Mobile / telephony agent skills for Concinno. Unified on the MIT-licensed Twilio Python SDK — the most mature programmatic-telephony provider for SMS, voice, and WhatsApp Business. Device-side Android / iOS shell control is intentionally out of scope; that belongs to the Sancio runtime layer.
Why this package exists
HammerBench (and adjacent benchmarks) evaluate agents on realistic telephony / SaaS workflows. Concinno can drive Twilio today over plain HTTPS — no device emulator, no OS-level hook — making this the blue-ocean entry point for mobile skills in the Concinno ecosystem.
Status
MVP (0.1.0) — three one-shot tools:
| Tool class | Channel | Underlying API | SDK licence |
|---|---|---|---|
TwilioSms |
SMS | Twilio Programmable Messaging | MIT |
TwilioWhatsApp |
Twilio WhatsApp Business (Messaging) | MIT | |
TwilioVoiceCall |
Voice | Twilio Programmable Voice | MIT |
Microsoft Teams / push-only providers (Pushover, ntfy) are deferred until they land in a dedicated sibling sub-package.
Install
pip install concinno-skills-mobile
twilio>=9.0 is a hard dependency and is pulled in automatically.
Twilio account requirements
You need a Twilio account (trial or paid). Outbound SMS / WhatsApp
messages and voice calls cost money per Twilio's per-country
pricing. A WARNING-level log line is emitted to stderr before every
outbound call so the billing risk is visible in agent traces.
- SMS: buy (or port) a Twilio phone number in a country you need to send to; long-code numbers are rate-limited to roughly 1 msg/sec.
- WhatsApp: register a WhatsApp-enabled sender (Twilio Sandbox for
trials or a fully-verified Business sender for production) — addresses
use the
whatsapp:+<digits>prefix on bothtoandfrom_. - Voice: any Twilio number with Voice capability works; the call behaviour is driven by either inline TwiML XML or a URL pointing at a hosted TwiML document.
Credentials
The Twilio account_sid + auth_token are read from the Concinno
CredentialStore, which consults (in order):
- Process runtime overrides via
CredentialStore.set(...). - Env var
CONCINNO_CRED_<UPPER_KEY>. ~/.concinno/credentials.json.
| Key | Env var |
|---|---|
twilio_account_sid |
CONCINNO_CRED_TWILIO_ACCOUNT_SID |
twilio_auth_token |
CONCINNO_CRED_TWILIO_AUTH_TOKEN |
Example ~/.concinno/credentials.json:
{
"twilio_account_sid": "ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"twilio_auth_token": "your_auth_token_here"
}
If either credential is missing the tool returns
{"error": "no twilio credentials — set account_sid + auth_token via CredentialStore / env"} rather than crashing.
Phone number formats
All destination / sender numbers are validated locally before the network call, both to catch typos early and to avoid burning billable round-trips on malformed input:
- SMS / Voice: E.164 only (
+<country_code><digits>, max 15 digits). - WhatsApp:
whatsapp:+<country_code><digits>.
Both sides of every send / call are validated with the same rule.
Usage via Concinno ToolRegistry
When the consumer sets CONCINNO_LOAD_PLUGINS=1, the default registry
auto-mounts every mobile tool:
import os
os.environ["CONCINNO_LOAD_PLUGINS"] = "1"
from concinno.tools.registry import get_default_registry
reg = get_default_registry()
assert {"TwilioSms", "TwilioWhatsApp", "TwilioVoiceCall"} <= set(
reg.list_deferred()
)
sms = reg.get("TwilioSms")
sms.call(
action="send",
to="+14155551234",
from_="+14155550000",
body="Hello from Concinno",
)
Direct Python usage
from concinno_skills_mobile import (
TwilioSms,
TwilioWhatsApp,
TwilioVoiceCall,
)
TwilioSms().call(
action="send",
to="+14155551234",
from_="+14155550000",
body="hi",
)
TwilioWhatsApp().call(
action="send",
to="whatsapp:+14155551234",
from_="whatsapp:+14155550000",
body="hi",
)
TwilioVoiceCall().call(
action="create",
to="+14155551234",
from_="+14155550000",
twiml="<Response><Say>Hi from Concinno</Say></Response>",
)
All tools return {"ok": True, ...} on success or {"error": "..."}
on failure — same shape as other Concinno built-in tools. No
exceptions escape the call() surface.
Concurrency
All three tools set is_concurrency_safe = False. Twilio rate limits
(per-from-number for SMS; per-subaccount for voice; per-sender for
WhatsApp) make serial dispatch the sane default; Concinno's scheduler
will honour this automatically.
License
Apache-2.0. See LICENSE in the Concinno monorepo.
Metadata
Release files for concinno-skills-mobile 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| concinno_skills_mobile-0.1.0.tar.gz | 40.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| concinno_skills_mobile-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 55.5 kB
Release files / concinno_skills_mobile-0.1.0.tar.gz
| Download URL | concinno_skills_mobile-0.1.0.tar.gz |
|---|---|
| Size | 40.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
de5b92d19482881e7b4f17c34f7c298ca69e9eb02f21e43e670ef3262b662944
|
|
BLAKE2b-256 checksum How to use checksums |
085bc9826ee4f9516ef5af9858488bafccda1f921bc131400c3453c9ebc5ad82
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|
Release files / concinno_skills_mobile-0.1.0-py3-none-any.whl
| Download URL | concinno_skills_mobile-0.1.0-py3-none-any.whl |
|---|---|
| Size | 14.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a02cec5a65822f28e367c44bc2c84d09b50f3d566087b006b3ab7b22573606bb
|
|
BLAKE2b-256 checksum How to use checksums |
a30baa4d9b562b0beda726f7028402f0dd18b1deebd45980d045c301107b7245
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.11.9
|