Files
2026-07-13 13:39:38 +08:00

7.2 KiB

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_KEY
  • HAMMING_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_metadata
  • external_links
  • session_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"},
    },
)

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_capture on the final /collect payload.
  • 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_url derived from a deterministic output path.

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_ctx when calling hamming.attach_session(...).
  • Managed remote recording modes require deterministic artifact URL resolution via recording.s3.public_url_base or recording.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=True is still supported as a backward-compatible alias for recording={"mode": "session_audio"}.
  • Managed remote recording modes stop egress on close and send deterministic artifact URLs through the same /api/rest/v2/collect ingestion path.

Troubleshooting

  • RuntimeError: hamming is not configured
    • Call hamming.configure_hamming(...) before hamming.attach_session(...).
  • ValueError: Hamming API key required
    • Set HAMMING_API_KEY or pass api_key=....
  • external_agent_id is required
    • Set HAMMING_EXTERNAL_AGENT_ID or pass external_agent_id=....
  • Unsupported recording mode
    • Use none, session_audio, participant_egress, or room_composite.
  • recording mode 'participant_egress' requires LiveKit server credentials
    • Provide recording.livekit or set LIVEKIT_URL, LIVEKIT_API_KEY, and LIVEKIT_API_SECRET.
  • recording mode 'participant_egress' requires deterministic artifact URL resolution
    • Provide recording.s3.public_url_base or recording.s3.bucket + recording.s3.region.
  • recording mode 'participant_egress' requires JobContext
    • Pass job_ctx=ctx to hamming.attach_session(...) or call it from inside the active LiveKit job.