Skip to main content

SuperBryn SDK — sync your voice-agent configuration to SuperBryn for review, versioning, and monitoring

Project description

SuperBryn Agent Sync

PyPI version Python 3.10+ License: MIT Zero dependencies

Sync your voice-agent configuration to SuperBryn for review, versioning, and monitoring — from any framework (Pipecat, LiveKit) or provider (Vapi, Retell, ElevenLabs, Bland, Bolna, …), or straight from your source code.

A pushed manifest never changes your live agent directly. It lands as a pending draft that you review, diff, and approve in the SuperBryn dashboard. On approval (once verification passes), SuperBryn promotes the draft to a new agent version.

Features

  • Zero runtime dependencies — the blocking client uses stdlib urllib; add aiohttp only if you want the async client.
  • Draft-first sync — every push lands as a pending draft for human review; nothing goes live without approval.
  • Client-side content hashing — same RFC 8785 (JCS) + SHA-256 hashing as the server, so you can pre-check and skip no-op pushes.
  • Manifest builder — fluent, typed builder for identity, behavior, LLM / STT / TTS / voice, tools, language, telephony, guardrails, and concurrency.
  • Framework adapters — build a manifest directly from a Pipecat pipeline or a LiveKit agent; public attributes only, never API keys.
  • Provider translators — turn Vapi / Retell / ElevenLabs / Bland / Bolna agent JSON into a manifest, best-effort and never erroring on unknown fields.
  • Source-code extractioncodescan statically scans your agent's code (Python ast, conservative JS/TS regexes) to fill prompt, models, voice, and phone number when no API can.
  • Drift detectioncheck_drift(manifest) tells you when local config differs from the live version.
  • Typed errors — auth, scope, validation, business-rule, and rate-limit failures each raise a distinct exception with details.
  • Bundled JSON Schema — the canonical manifest schema ships inside the package.

Prerequisites

  • Python 3.10+
  • An agent-scoped API key created in the SuperBryn dashboard (Developers → API Keys, scope: Single agent). Org-wide keys are rejected by the sync endpoints.

Install

pip install superbryn-agent-sync            # zero runtime dependencies
pip install "superbryn-agent-sync[async]"   # + aiohttp for the async client

The import name is superbryn:

from superbryn import Superbryn, Manifest

Quick Start

  1. Set your agent-scoped API key in the environment:

    export SUPERBRYN_API_KEY="sk_agent_..."
    
  2. Build a manifest and sync it:

    from superbryn import Superbryn, Manifest
    
    manifest = (
        Manifest.builder(source="custom")
        .set_identity(name="Support Agent", type="inbound", agent_modality="voice")
        .set_behavior(prompt=open("system_prompt.txt").read())
        .set_llm(provider="openai", model="gpt-4o", temperature=0.7, max_tokens=1024)
        .set_stt(provider="deepgram", model="nova-2", language="en-US")
        .set_tts(provider="cartesia", model="sonic-2")
        .set_voice(provider="cartesia", voice_id="a0e99841-...")
        .add_tool(
            name="lookup_order",
            description="Look up an order by ID",
            schema={"type": "object", "properties": {}},
            server={"type": "http", "url": "https://api.example.com/orders"},
        )
        .set_language(primary_language="en-US", additional_languages=[{"code": "es-US", "priority": 1}])
        .set_telephony(phone_number="+15551234567")
        .set_policy_guardrails(open("guardrails.md").read())
        .set_concurrency_calls(10)
        .build()
    )
    
    client = Superbryn()  # or Superbryn(api_key="sk_agent_...")
    result = client.sync(manifest)
    # {"agent_row_id": "...", "approval_status": "pending", "verification_status": "...",
    #  "hash": "...", "change_types": [...]}
    
  3. Open the SuperBryn dashboard, review the pending draft, and approve it to promote a new agent version.

Every manifest field is optional — send only what your integration knows. An empty manifest is valid.

Client Surface

client.sync(manifest)                  # push; lands as pending draft (or no-op)
client.sync(manifest, precheck=True)   # GET live hash first, skip push if unchanged
client.get_config()                    # live version's manifest + content hash
client.withdraw_draft()                # withdraw your pending draft
client.check_drift(manifest)           # True when local != live (hash compare)

The async client mirrors the same surface (pip install "superbryn-agent-sync[async]"):

from superbryn import AsyncSuperbryn

result = await AsyncSuperbryn(api_key="sk_agent_...").sync(manifest)

Hash Pre-Check

The SDK implements the same RFC 8785 (JCS) + SHA-256 content hashing as the server, so a client-side hash always agrees with the server's:

from superbryn import compute_manifest_hash

local_hash = compute_manifest_hash(manifest)   # == manifest.hash

Framework Adapters

Lazy submodules — the base package depends on neither framework.

Pipecat

from superbryn import Superbryn
from superbryn.pipecat import build_manifest_from_pipeline

manifest = build_manifest_from_pipeline(
    pipeline,
    identity={"name": "Support Agent", "type": "inbound", "agent_modality": "voice"},
    behavior={"prompt": open("prompt.txt").read()},
    policy_guardrails=open("guardrails.md").read(),
)
Superbryn(api_key="sk_agent_...").sync(manifest)

Walks pipeline._processors and fills llm / stt / tts / voice automatically. Extractors read public attributes only — never API keys.

LiveKit

from superbryn import Superbryn
from superbryn.livekit import build_manifest_from_agent

manifest = build_manifest_from_agent(
    agent,
    identity={"name": "Support Agent", "type": "inbound", "agent_modality": "voice"},
    policy_guardrails=open("guardrails.md").read(),
)
Superbryn(api_key="sk_agent_...").sync(manifest)

Reads agent.llm / agent.stt / agent.tts and uses agent.instructions as the behavior prompt.

Provider Translators

For SaaS platforms the agent config lives in their cloud, not in your process. Fetch the agent JSON from the provider's API, then translate it to a manifest:

import requests
from superbryn import Superbryn
from superbryn.translators import vapi

raw = requests.get(
    "https://api.vapi.ai/assistant/ASSISTANT_ID",
    headers={"Authorization": "Bearer VAPI_KEY"},
).json()

manifest = vapi.manifest_from_assistant(raw)
Superbryn(api_key="sk_agent_...").sync(manifest)
Provider Translator Input
Vapi translators.vapi.manifest_from_assistant(raw) GET /assistant/:id
Retell translators.retell.manifest_from_agent(agent, llm) GET /get-agent/:id + GET /get-retell-llm/:llm_id
ElevenLabs translators.elevenlabs.manifest_from_agent(raw) GET /v1/convai/agents/:id
Bland translators.bland.manifest_from_agent(raw) GET /v1/agents/:id
Bolna translators.bolna.manifest_from_agent(raw) GET /v2/agent/:id
Hooman Labs / Shunya Labs / custom translators.generic.manifest_from_prompt(prompt, source=...) or codescan.build_manifest_from_source(...) (see below) your own prompt + known pipeline facts (no public agent-read API yet)

All translators are best-effort — unknown or missing fields degrade to a sparser manifest, never an error.

Source-Code Extraction (works for every provider)

You never know in advance what a provider's public API returns — some give back the full agent config, others little more than an id, and some (Hooman Labs, Shunya Labs, in-house stacks) have no agent-read API at all. Whatever the API does or doesn't return, the customer's own code — the place that instantiates the provider's package/SDK — is always available. superbryn.codescan statically scans that code and extracts the prompt, model, voice, language, temperature and phone number.

As the sole source (no API, or the API returned nothing useful):

from superbryn import Superbryn
from superbryn.codescan import build_manifest_from_source

manifest = build_manifest_from_source(
    "path/to/agent-project",          # directory or single file
    source="hooman-labs",
    identity={"name": "Support Agent", "type": "inbound"},  # anything the scan can't see
)
Superbryn(api_key="sk_agent_...").sync(manifest)

As a gap filler after ANY translator — the scan adds only the fields the provider's API didn't provide, and API-provided values always win:

from superbryn import codescan, translators

manifest = translators.vapi.manifest_from_assistant(raw)          # may be sparse
manifest = codescan.fill_manifest_gaps(manifest, "path/to/agent-project")

How it works:

  • Python files are parsed with ast: keyword arguments on any call (prompt=, instructions=, model=, voice_id=, ...) are collected, and simple variable references (prompt=SYSTEM_PROMPT) resolve to their assigned string constants.
  • JS/TS files are scanned with conservative regexes for the same keys in object-literal form (systemPrompt: "...", voiceId: '...').
  • Called class names classify hits per pipeline stage (DeepgramSTTService → stt/deepgram, CartesiaTTSService → tts/cartesia), so an STT model never lands in the llm block.
  • The longest prompt-key string wins as behavior.prompt; node_modules, virtualenvs and build output are skipped.

Extraction is best-effort and read-only. Run it in CI next to the agent code and every deploy syncs the latest config. Use scan_source(path) to inspect the raw findings before building a manifest.

Manifest Fields

Override sections accept exactly the fields of the canonical manifest schema (unknown keys raise ValueError locally — the endpoint rejects them anyway):

Section Fields
identity name, type (inbound/outbound), agent_modality (voice/chat), description, pain_point, gender, age, dob
behavior prompt, flow
llm / stt / tts / voice provider, model / voice_id, plus per-block extras (temperature, max_tokens, language, fallback, extra)
tools list of {name, description, schema, server: {type, url}}
language primary_language, additional_languages: [{code, priority}]
telephony phone_number, ivr_config

Plus top-level strings/ints: policy_guardrails, additional_details, concurrency_calls.

The canonical JSON Schema is bundled with the package:

from superbryn import load_manifest_schema

schema = load_manifest_schema()

Typed Errors

from superbryn import (
    AuthenticationError,     # 401 — bad/revoked key
    ScopeError,              # 403 — key is not agent-scoped
    NotFoundError,           # 404 — no live version / no pending draft
    ManifestValidationError, # 400 — schema failure (has .details)
    BusinessRuleError,       # 422 — semantic rule failure (has .details)
    RateLimitError,          # 429 — back off and retry
)

Troubleshooting

Enable debug logs

import logging
logging.basicConfig(level=logging.DEBUG)
logging.getLogger("superbryn").setLevel(logging.DEBUG)

Common errors

Error Cause Fix
ConfigurationError: no API key Missing API key Pass api_key= or set SUPERBRYN_API_KEY
AuthenticationError (401) Invalid or revoked key Verify the key in SuperBryn → Developers → API Keys
ScopeError (403) Org-wide key used Create an agent-scoped key (scope: Single agent)
NotFoundError (404) No live version / no pending draft Sync a manifest first, or skip the withdraw
ManifestValidationError (400) Manifest fails schema validation Inspect .details for the offending fields
BusinessRuleError (422) Semantic rule failure Inspect .details and adjust the manifest
RateLimitError (429) Too many requests Back off and retry

Environment Variables

Variable Meaning
SUPERBRYN_API_KEY Agent-scoped API key (fallback for api_key=)
SUPERBRYN_BASE_URL API base URL (default https://api.superbryn.com)

Links

Support

License

This project is licensed under the MIT License — see the LICENSE file for details.


Made with ❤️ by SuperBryn

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

superbryn_agent_sync-0.1.3.tar.gz (38.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

superbryn_agent_sync-0.1.3-py3-none-any.whl (36.6 kB view details)

Uploaded Python 3

File details

Details for the file superbryn_agent_sync-0.1.3.tar.gz.

File metadata

  • Download URL: superbryn_agent_sync-0.1.3.tar.gz
  • Upload date:
  • Size: 38.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for superbryn_agent_sync-0.1.3.tar.gz
Algorithm Hash digest
SHA256 da04687336453b359332a0e3db3f6f1a1c11c6eae242afa03ec4c1c6badcc0a0
MD5 8a0ca23a8934d99f4e52965a0016d287
BLAKE2b-256 457282c4ec6aec5bab955f7f4b52e76885fea7fc9981cf03bca250e910fe3895

See more details on using hashes here.

File details

Details for the file superbryn_agent_sync-0.1.3-py3-none-any.whl.

File metadata

File hashes

Hashes for superbryn_agent_sync-0.1.3-py3-none-any.whl
Algorithm Hash digest
SHA256 5f6ebf3db1f0560e969c9c5ef827fa623dc6dc167b83f1f6b029536ede6b4ba2
MD5 8d5c247d68aeedbfa2e1cc3839493b95
BLAKE2b-256 50074d36bf9a19aad6da188e5f29014037ef51bc7cae77501309e8daaca6b781

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page