API Reference
SentinelClient
Thymia Sentinel client for streaming audio to the Lyra server.
Streams both user and agent audio, plus transcripts, to enable multimodal safety analysis combining speech biomarkers with conversation content.
Example using decorators
from thymia_sentinel import SentinelClient
sentinel = SentinelClient(
user_label="user-123",
policies=["demo_wellbeing_awareness"],
)
@sentinel.on_policy_result
async def handle_policy(result):
level = result["result"]["classification"]["level"]
if level >= 2:
print(f"Elevated risk: {result['result']['concerns']}")
@sentinel.on_progress
async def handle_progress(result):
for name, status in result["biomarkers"].items():
print(f"{name}: {status['speech_seconds']:.1f}s")
await sentinel.connect()
# In your audio loop:
await sentinel.send_user_audio(audio_bytes)
await sentinel.send_agent_audio(audio_bytes)
await sentinel.send_user_transcript("Hello")
await sentinel.send_agent_transcript("Hi there!")
await sentinel.close()
Example using callbacks
Attributes:
| Name | Type | Description |
|---|---|---|
user_label |
Optional unique identifier for the user being monitored |
|
date_of_birth |
Optional user's date of birth (YYYY-MM-DD format, improves accuracy) |
|
birth_sex |
Optional user's birth sex ("MALE" or "FEMALE", improves accuracy) |
|
language |
Language code (default: "en-GB") |
|
sample_rate |
Audio sample rate in Hz (default: 16000) |
connected
property
Whether the client is currently connected.
__init__(user_label=None, date_of_birth=None, birth_sex=None, language='en-GB', policies=None, biomarkers=None, on_policy_result=None, on_progress_result=None, progress_updates_frequency=1.0, custom_policies=None, sample_rate=DEFAULT_SAMPLE_RATE, server_url=None, api_key=None)
Initialize the Sentinel client.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
user_label
|
Optional[str]
|
Optional unique identifier for the user (UUID format recommended) |
None
|
date_of_birth
|
Optional[str]
|
Optional date of birth in YYYY-MM-DD format (improves accuracy, imputed from voice if omitted) |
None
|
birth_sex
|
Optional[str]
|
Optional, either "MALE" or "FEMALE" (improves accuracy, imputed from voice if omitted) |
None
|
language
|
str
|
Language code (default: "en-GB") |
'en-GB'
|
policies
|
Optional[list[str]]
|
List of policies to execute (e.g., ["demo_wellbeing_awareness"]) |
None
|
biomarkers
|
Optional[list[str]]
|
List of biomarkers to extract (default: ["helios"]) |
None
|
on_policy_result
|
Optional[Union[Callable[[PolicyResult], None], Callable[[PolicyResult], Awaitable[None]]]]
|
Callback for policy results (sync or async) |
None
|
on_progress_result
|
Optional[Union[Callable[[ProgressResult], None], Callable[[ProgressResult], Awaitable[None]]]]
|
Callback for progress updates (sync or async) |
None
|
progress_updates_frequency
|
float
|
How often to receive progress updates in seconds |
1.0
|
custom_policies
|
Optional[list[dict]]
|
Optional inline policy definitions (requires feature flag on API key) |
None
|
sample_rate
|
int
|
Audio sample rate in Hz (default: 16000) |
DEFAULT_SAMPLE_RATE
|
server_url
|
Optional[str]
|
WebSocket server URL (default: from THYMIA_SERVER_URL env or wss://ws.thymia.ai) |
None
|
api_key
|
Optional[str]
|
Thymia API key (default: from THYMIA_API_KEY env) |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If THYMIA_API_KEY is not provided and not in environment |
close()
async
Close the connection to the Lyra server.
Cancels the receive task and closes the WebSocket connection.
connect()
async
Connect to the Lyra server and start receiving events.
Establishes WebSocket connection, sends configuration, and starts the background task to receive server events.
on_policy_result(func)
Decorator to register a policy result handler.
The handler will be called whenever a policy result is received from the server. Multiple handlers can be registered.
Example
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
F
|
Async or sync function that receives a PolicyResult |
required |
Returns:
| Type | Description |
|---|---|
F
|
The original function (unchanged) |
on_progress(func)
Decorator to register a progress handler.
The handler will be called periodically with biomarker extraction progress updates. Multiple handlers can be registered.
Note: Registering a progress handler automatically enables progress updates from the server.
Example
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
func
|
F
|
Async or sync function that receives a ProgressResult |
required |
Returns:
| Type | Description |
|---|---|
F
|
The original function (unchanged) |
send_agent_audio(audio_data)
async
Send agent audio to the Lyra server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audio_data
|
bytes
|
PCM16 audio bytes at the configured sample rate |
required |
send_agent_transcript(text, is_final=True)
async
Send agent transcript to the Lyra server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The text that the agent is speaking |
required |
is_final
|
bool
|
Whether this is a final transcript (default: True) |
True
|
send_user_audio(audio_data)
async
Send user audio to the Lyra server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
audio_data
|
bytes
|
PCM16 audio bytes at the configured sample rate |
required |
send_user_transcript(text, is_final=True)
async
Send user transcript to the Lyra server.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
text
|
str
|
The transcribed text from the user |
required |
is_final
|
bool
|
Whether this is a final transcript (default: True) |
True
|
Event Handlers
Register handlers using decorators or constructor callbacks:
sentinel = SentinelClient(
user_label="user-123",
policies=["demo_wellbeing_awareness"],
)
# Decorator pattern (recommended)
@sentinel.on_policy_result
async def handle_policy(result: PolicyResult):
level = result["result"]["classification"]["level"]
if level >= 2:
await take_action(result)
@sentinel.on_progress
async def handle_progress(result: ProgressResult):
for name, status in result["biomarkers"].items():
print(f"{name}: {status['speech_seconds']:.1f}s")
# Alternative: constructor callbacks
sentinel = SentinelClient(
on_policy_result=handle_policy,
on_progress_result=handle_progress,
# ...
)
Multiple handlers can be registered for each event type. Both sync and async handlers are supported.
Type Definitions
PolicyResult
The main result type received from the Lyra server.
class PolicyResult(TypedDict, total=False):
type: Literal["POLICY_RESULT"]
policy: str # Executor type (e.g., "safety_analysis", "passthrough")
policy_name: str # Policy name (e.g., "demo_wellbeing_awareness", "demo_field_extraction")
triggered_at_turn: int # User turn that triggered this policy
timestamp: float # Unix timestamp
result: dict # Policy-specific result data
Note
policy is the executor type (e.g., "safety_analysis"), while policy_name is the name of the specific policy from your org config (e.g., "demo_wellbeing_awareness"). When multiple policies share the same executor, use policy_name to distinguish them.
ProgressResult
Progress update for biomarker collection.
class ProgressResult(TypedDict, total=False):
type: Literal["PROGRESS"]
biomarkers: dict[str, BiomarkerProgress]
timestamp: float
class BiomarkerProgress(TypedDict, total=False):
speech_seconds: float # Seconds of speech collected
trigger_seconds: float # Seconds required to trigger
processing: bool # Whether analysis is in progress
Wellbeing Awareness Analysis Types
class ReasonerClassification(TypedDict):
level: int # Awareness level 0-3
alert: str
confidence: Literal["low", "medium", "high"]
class ReasonerRecommendedActions(TypedDict, total=False):
for_agent: str # Guidance for the AI agent
for_human_reviewer: str | None # Notes for human reviewers
urgency: Literal["routine", "follow_up", "attentive", "supportive"]
class ReasonerConcordanceAnalysis(TypedDict, total=False):
scenario: str # mood_not_discussed, concordance, minimization, amplification
agreement_level: str # high, moderate, low, n/a
mismatch_type: str | None
mismatch_severity: str # none, mild, moderate, severe
class ReasonerFlags(TypedDict, total=False):
suicidal_content: bool
severe_mismatch: bool
mood_not_yet_discussed: bool
critical_symptoms: bool
Biomarker Summary
class ReasonerBiomarkerSummary(BaseModel):
# Helios wellness scores (0-1)
distress: float | None
stress: float | None
burnout: float | None
fatigue: float | None
low_self_esteem: float | None
# Psyche scores (0-1)
neutral: float | None
happy: float | None
sad: float | None
angry: float | None
fearful: float | None
disgusted: float | None
surprised: float | None
# Apollo disorder probabilities (0-1)
depression_probability: float | None
anxiety_probability: float | None
# Depression symptoms (0-1)
symptom_anhedonia: float | None
symptom_low_mood: float | None
symptom_sleep_issues: float | None
symptom_low_energy: float | None
symptom_appetite: float | None
symptom_worthlessness: float | None
symptom_concentration: float | None
symptom_psychomotor: float | None
# Anxiety symptoms (0-1)
symptom_nervousness: float | None
symptom_uncontrollable_worry: float | None
symptom_excessive_worry: float | None
symptom_trouble_relaxing: float | None
symptom_restlessness: float | None
symptom_irritability: float | None
symptom_dread: float | None
# Summary
interpretation: str | None
Protocol Reference
WebSocket Messages
Configuration (Client → Server)
Sent immediately after connection:
{
"api_key": "your-api-key",
"user_label": "user-123",
"language": "en-GB",
"biomarkers": ["helios", "apollo"],
"policies": ["demo_wellbeing_awareness"],
"audio_config": {
"sample_rate": 16000,
"format": "pcm16",
"channels": 1
},
"progress_updates": {
"enabled": true,
"interval_seconds": 1.0
}
}
Audio Header (Client → Server)
Sent before each audio chunk:
{
"type": "AUDIO_HEADER",
"track": "user",
"format": "pcm16",
"sample_rate": 16000,
"channels": 1,
"bytes": 3200
}
Immediately followed by raw audio bytes.
Transcript (Client → Server)
{
"type": "TRANSCRIPT",
"speaker": "user",
"text": "I'm feeling okay today",
"is_final": true,
"language": "en-GB",
"timestamp": 1234567890.123
}
Policy Result (Server → Client)
{
"type": "POLICY_RESULT",
"policy": "safety_analysis",
"policy_name": "demo_wellbeing_awareness",
"triggered_at_turn": 3,
"timestamp": 1234567890.456,
"result": {
"type": "safety_analysis",
"classification": { ... },
"concerns": [ ... ],
"recommended_actions": { ... }
}
}
Progress (Server → Client)
{
"type": "PROGRESS",
"biomarkers": {
"helios": {
"speech_seconds": 8.2,
"trigger_seconds": 10.0,
"processing": false
}
},
"timestamp": 1234567890.789
}