ElevenLabs
Connect Suprflo to ElevenLabs Conversational AI over webhooks.
Install
pip install suprfloNo extra, and no ElevenLabs SDK: this module maps webhook payloads — plain dicts in, plain dicts out.
Read this first: it is not a plugin
ElevenLabs hosts the agent. The LLM turn runs on ElevenLabs' infrastructure, not in your process, so there is no in-process hook to inject memories through — unlike LangChain, LiveKit or Pipecat. The SDK's Conversation class exposes only fire-and-forget observers (callback_user_transcript, callback_agent_response) that return None, receive no context object, and fire when the turn is already underway.
So this integration is narrower than the others by necessity. It is honest about that rather than wrapping a hook that cannot work.
What you get
persist_transcript(client, payload, user_id=...)— turn a post-call webhook transcript into memories.recall_dynamic_variables(client, query, user_id=...)— build thedynamic_variablesfor a conversation-initiation webhook response, so recalled memories reach the agent through its prompt at conversation start.build_search_server_tool(api_key, user_id, base_url=...)— build the server-tool registration payload that lets an agent query Suprflo mid-conversation over HTTP.
Recall at conversation start
Respond to the conversation-initiation webhook with memories for the prompt. recall_dynamic_variables returns the whole response body, so return it as-is:
from suprflo import MemoryClient
from suprflo.integrations.elevenlabs import recall_dynamic_variables
client = MemoryClient(api_key="YOUR_API_KEY")
def on_conversation_initiation(payload):
return recall_dynamic_variables(
client, query="preferences", user_id=payload["user_id"]
)
# → {"type": "conversation_initiation_client_data",
# "dynamic_variables": {"suprflo_memories": "- likes tea\n- lives in Berlin"}}Reference in the agent's system prompt to place the recalled text. The variable is always defined — an empty string when nothing matched — because ElevenLabs errors on a prompt variable it cannot resolve.
Search mid-conversation
Register a server tool so the agent can query Suprflo during the call:
from suprflo.integrations.elevenlabs import build_search_server_tool
tool = build_search_server_tool(api_key="YOUR_API_KEY", user_id="alice")
# register `tool` on your agent via the ElevenLabs dashboard or APIThe payload embeds your API key in the request headers — build it server-side and never ship it to a browser.
Persist after the call
from suprflo.integrations.elevenlabs import persist_transcript
def on_post_call(payload):
persist_transcript(client, payload, user_id=payload["user_id"])ElevenLabs names the assistant side of a transcript agent; Suprflo (like OpenAI) calls it assistant. The adapter translates this.
Notes and limits
- Every function is synchronous, matching
MemoryClient. That suits a sync webhook handler (Flask/WSGI). From an async handler (FastAPIasync def) wrap the call inasyncio.to_thread, or it blocks the event loop. - The webhook payload shapes are written from the documented API and are unverified against live ElevenLabs traffic; the tests prove the mapping logic and nothing about ElevenLabs itself.
- For a genuine in-process pre-LLM hook, ElevenLabs' Speech Engine inverts the architecture (they do ASR/TTS/turn-taking, you own the LLM call), and their Custom LLM is the out-of-process equivalent. Neither is wrapped here: a wrapper guessed at would be worse than none.