Documentation Index
Fetch the complete documentation index at: https://docs.innate.bot/llms.txt
Use this file to discover all available pages before exploring further.
Digital skills enable the robot to interact with external services—sending emails, making API calls, retrieving information. These are always code skills, implementing explicit protocols and handling authentication, errors, and network conditions.
Characteristics
Unlike physical skills that deal with real-world variability, digital skills operate in a deterministic domain:
-
Protocol-based: Follow defined APIs and standards
-
Atomic: Many operations cannot be cancelled once started
-
Reliable: Once working, behavior is consistent
-
Network-dependent: Must handle connectivity issues
Built-in Skills
SendEmail
Sends email notifications, typically for alerts or status updates.
class SendEmail(Skill):
@property
def name(self):
return "send_email"
def guidelines(self):
return (
"Use to send an emergency email notification. Provide a subject and "
"message. You can optionally provide a list of recipients, otherwise "
"it will be sent to the default list. This should be used when a "
"potential emergency is detected and assistance might be required."
)
def execute(self, subject: str, message: str, recipients: list[str] = None):
# Send via SMTP
# Returns (message, SkillResult)
Parameters:
| Parameter | Type | Required | Description |
|---|
| subject | str | Yes | Email subject line. |
| message | str | Yes | Email body content. |
| recipients | list[str] | No | Recipients (defaults to configured list). |
SendPictureViaEmail
Sends an email with the robot’s current camera view attached.
class SendPictureViaEmail(Skill):
# Declare camera image dependency - updated at 50Hz while skill runs
image = RobotState(RobotStateType.LAST_MAIN_CAMERA_IMAGE_B64)
def execute(self, subject: str, message: str, recipient: str = None):
if not self.image:
return "No image available to send", SkillResult.FAILURE
# Attach image and send
This skill demonstrates state dependencies—using the RobotState descriptor to declare required robot state that the system updates at 50Hz.
RetrieveEmails
Fetches recent emails from configured account.
class RetrieveEmails(Skill):
def guidelines(self):
return (
"Use to retrieve recent emails from the configured email account. "
"Provide the number of emails to retrieve (default is 5). "
"Returns email subjects and content."
)
def execute(self, count: int = 5):
# Connect to IMAP, fetch emails
# Returns formatted email list
Creating Digital Skills
Template
import os
from brain_client.skill_types import Skill, SkillResult
class MyDigitalSkill(Skill):
def __init__(self, logger):
super().__init__(logger)
self.api_key = os.environ.get("SERVICE_API_KEY")
if not self.api_key:
raise ValueError("SERVICE_API_KEY not configured")
@property
def name(self):
return "my_digital_skill"
def guidelines(self):
return "Use when [describe appropriate use cases]"
def execute(self, param: str):
try:
# Call external service
result = self._call_service(param)
return f"Success: {result}", SkillResult.SUCCESS
except TimeoutError:
return "Service timed out", SkillResult.FAILURE
except Exception as e:
return f"Error: {e}", SkillResult.FAILURE
def cancel(self):
return "Operation cannot be cancelled"
Best Practices
Authentication
-
Store credentials in environment variables or secret managers
-
Never hardcode passwords or API keys
-
Validate credentials at initialization
Error Handling
def execute(self, query: str):
try:
response = self.client.call(query, timeout=10)
return f"Result: {response}", SkillResult.SUCCESS
except RateLimitError:
return "Rate limit exceeded", SkillResult.FAILURE
except NetworkError:
return "Network unavailable", SkillResult.FAILURE
except Exception as e:
return f"Unexpected error: {e}", SkillResult.FAILURE
Timeouts
-
Always set explicit timeouts on network calls
-
Prevent blocking indefinitely on slow services
Idempotency
-
Design operations to be safely retryable when possible
-
Consider partial failure scenarios
Requesting Robot State
Skills declare sensor data dependencies using the RobotState descriptor:
from brain_client.skill_types import RobotState, RobotStateType
class MySkill(Skill):
# Declare state dependencies at class level
image = RobotState(RobotStateType.LAST_MAIN_CAMERA_IMAGE_B64)
odom = RobotState(RobotStateType.LAST_ODOM)
def execute(self):
if self.image:
# Use the latest camera frame
pass
The system automatically updates declared state at 50Hz while your skill runs. Always check for None on first access.
Available state types:
| State Type | Description |
|---|
| LAST_MAIN_CAMERA_IMAGE_B64 | Latest camera frame (base64 JPEG). |
| LAST_ODOM | Current odometry. |
| LAST_MAP | Occupancy grid. |
| LAST_HEAD_POSITION | Head tilt angle. |
See Robot State for more details on the RobotState system.
Cancellation
Many digital operations are atomic and cannot be meaningfully cancelled:
def cancel(self):
return "Email sending is an atomic operation that cannot be canceled once started"
BASIC understands this limitation and factors it into planning decisions.