Hamming plugin for LiveKit Agents
Post-call monitoring and session export for LiveKit Agents with Hamming.
Installation
Install the plugin from a checked out repository or extracted source archive:
python -m pip install ./livekit-plugins/livekit-plugins-hamming
Pre-requisites
You will need Hamming credentials before configuring the plugin.
HAMMING_API_KEYHAMMING_EXTERNAL_AGENT_ID
Credentials can be passed directly or through environment variables.
Usage
import os
from livekit.agents import AgentSession, JobContext
from livekit.plugins import hamming
async def entrypoint(ctx: JobContext) -> None:
await ctx.connect()
hamming.configure_hamming(
api_key=os.environ["HAMMING_API_KEY"],
external_agent_id=os.environ["HAMMING_EXTERNAL_AGENT_ID"],
recording={"mode": "session_audio"},
)
session = AgentSession()
hamming.attach_session(
session,
job_ctx=ctx,
customer_metadata={
"deployment": {
"environment": "prod",
"prompt_version": "v17",
},
"experiment": {
"variant": "B",
},
},
external_links=[
{
"label": "CRM Contact",
"url": "https://crm.example.com/contact/123",
"source": "salesforce",
}
],
session_mode="testing",
)
Unified Responsibilities
The Hamming plugin is intentionally focused on one responsibility:
- post-call session export for Call Review and testing workflows
Use attach_session(...) for per-call review/testing context:
customer_metadataexternal_linkssession_mode
Call Review And Testing Fields
customer_metadata
Use customer_metadata for filterable customer-owned metadata:
hamming.attach_session(
session,
job_ctx=ctx,
customer_metadata={
"deployment": {"environment": "prod"},
"experiment": {"variant": "B"},
},
)
external_links
Use external_links for click-through operator links:
hamming.attach_session(
session,
job_ctx=ctx,
external_links=[
{
"label": "CRM Contact",
"url": "https://crm.example.com/contact/123",
"source": "salesforce",
"description": "Primary customer record",
}
],
)
session_mode
Use session_mode="testing" when the call is part of a testing workflow:
hamming.attach_session(
session,
job_ctx=ctx,
session_mode="testing",
)
Recording Modes
The plugin supports explicit recording modes through configure_hamming(recording=...).
If recording is omitted, the plugin exports monitoring payloads only and does not start or resolve recordings.
none- Send monitoring payload only.
session_audio- Use LiveKit session recording and inline
recording_captureon the final/collectpayload.
- Use LiveKit session recording and inline
participant_egress- Start managed LiveKit participant egress and send dual-track recording URLs derived from deterministic output paths.
room_composite- Start managed LiveKit room composite egress and send a single
recording_urlderived from a deterministic output path.
- Start managed LiveKit room composite egress and send a single
Session Audio (Default Simple Path)
hamming.configure_hamming(
api_key=os.environ["HAMMING_API_KEY"],
external_agent_id=os.environ["HAMMING_EXTERNAL_AGENT_ID"],
recording={"mode": "session_audio"},
)
Managed Participant Egress
hamming.configure_hamming(
api_key=os.environ["HAMMING_API_KEY"],
external_agent_id=os.environ["HAMMING_EXTERNAL_AGENT_ID"],
recording={
"mode": "participant_egress",
"livekit": {
"url": os.environ["LIVEKIT_URL"],
"api_key": os.environ["LIVEKIT_API_KEY"],
"api_secret": os.environ["LIVEKIT_API_SECRET"],
},
"s3": {
# Required for deterministic artifact URL resolution.
"public_url_base": os.environ.get("LIVEKIT_RECORDING_PUBLIC_URL_BASE", ""),
# Optional. Include upload credentials only if the plugin should write
# directly to S3 instead of relying on LiveKit project defaults.
"access_key": os.environ.get("LIVEKIT_RECORDING_S3_ACCESS_KEY", ""),
"secret": os.environ.get("LIVEKIT_RECORDING_S3_SECRET", ""),
"region": os.environ.get("LIVEKIT_RECORDING_S3_REGION", ""),
"bucket": os.environ.get("LIVEKIT_RECORDING_S3_BUCKET", ""),
},
},
)
Managed Room Composite
hamming.configure_hamming(
api_key=os.environ["HAMMING_API_KEY"],
external_agent_id=os.environ["HAMMING_EXTERNAL_AGENT_ID"],
recording={
"mode": "room_composite",
"livekit": {
"url": os.environ["LIVEKIT_URL"],
"api_key": os.environ["LIVEKIT_API_KEY"],
"api_secret": os.environ["LIVEKIT_API_SECRET"],
},
"audio_only": True,
"file_type": "ogg",
},
)
Notes:
- Managed remote recording modes require LiveKit server API credentials.
- Managed remote recording modes also require
job_ctxwhen callinghamming.attach_session(...). - Managed remote recording modes require deterministic artifact URL resolution via
recording.s3.public_url_baseorrecording.s3.bucket+recording.s3.region. - If you provide full S3 credentials, the plugin uses those upload settings for egress output.
- If you omit S3 upload credentials, your LiveKit project must already have default file output storage configured.
- The plugin does not poll LiveKit for completed artifact locations; it derives the final public URLs from the configured output path.
Verify configuration
import os
from livekit.plugins import hamming
report = hamming.doctor(api_key=os.environ["HAMMING_API_KEY"])
print(report.to_dict())
Notes
- Sessions are exported when attached through
hamming.attach_session(...). - Recording is opt-in. Omitting
recording=...sends monitoring payloads without recording artifacts. auto_record_audio=Trueis still supported as a backward-compatible alias forrecording={"mode": "session_audio"}.- Managed remote recording modes stop egress on close and send deterministic artifact URLs through the same
/api/rest/v2/collectingestion path.
Troubleshooting
RuntimeError: hamming is not configured- Call
hamming.configure_hamming(...)beforehamming.attach_session(...).
- Call
ValueError: Hamming API key required- Set
HAMMING_API_KEYor passapi_key=....
- Set
external_agent_id is required- Set
HAMMING_EXTERNAL_AGENT_IDor passexternal_agent_id=....
- Set
Unsupported recording mode- Use
none,session_audio,participant_egress, orroom_composite.
- Use
recording mode 'participant_egress' requires LiveKit server credentials- Provide
recording.livekitor setLIVEKIT_URL,LIVEKIT_API_KEY, andLIVEKIT_API_SECRET.
- Provide
recording mode 'participant_egress' requires deterministic artifact URL resolution- Provide
recording.s3.public_url_baseorrecording.s3.bucket+recording.s3.region.
- Provide
recording mode 'participant_egress' requires JobContext- Pass
job_ctx=ctxtohamming.attach_session(...)or call it from inside the active LiveKit job.
- Pass