Skip to content

refactor: Abstract ExternalAgentProvider for upstream EVA contribution#12

Merged
jamestwhedbee merged 3 commits intomainfrom
refactor/abstract-external-agent-provider
Mar 31, 2026
Merged

refactor: Abstract ExternalAgentProvider for upstream EVA contribution#12
jamestwhedbee merged 3 commits intomainfrom
refactor/abstract-external-agent-provider

Conversation

@jamestwhedbee
Copy link
Copy Markdown
Member

Summary

Refactors the Telnyx telephony bridge into a clean provider-based abstraction so that upstream ServiceNow/eva can easily extend EVA to support additional hosted voice agent APIs (ElevenLabs Conversational AI, Deepgram Voice Agent, OpenAI Realtime, etc.).

This is prep for an upstream issue targeting the Extended Leaderboard roadmap item:

More cascade and speech-to-speech systems evaluated and added to the findings including native voice agent APIs beyond Pipecat

Architecture

New eva.assistant.external package

src/eva/assistant/external/
├── __init__.py              # Factory: get_provider(config) → ExternalAgentProvider
├── base.py                  # ABCs: ExternalAgentProvider, BaseTelephonyTransport, BaseSegmentTranscriber
├── bridge.py                # ExternalAgentBridgeServer (provider-agnostic)
├── bridge_vad_observer.py   # VAD observer (already generic)
├── tool_webhook.py          # ToolWebhookService (provider routes injected)
└── providers/
    └── telnyx/
        ├── __init__.py      # TelnyxProvider implementation
        ├── config.py        # Re-export
        ├── transport.py     # CallControlTransport
        └── setup.py         # TelnyxAssistantManager

Key abstractions

  • ExternalAgentProvider ABC — plugin interface for hosted voice agent APIs:

    • create_transport() — transport connection to the external agent
    • setup() / teardown() — run-level lifecycle (e.g., create/restore assistant config)
    • fetch_intended_speech() — post-call enrichment for metrics
    • register_webhook_routes() — provider-specific webhook endpoints (e.g., DV webhook)
    • get_active_transport() — media stream routing
  • ExternalAgentBridgeServer — provider-agnostic bridge handling:

    • WebSocket ↔ transport audio routing
    • VAD observation and turn detection
    • Audio recording (user/assistant/mixed WAV)
    • Output persistence (transcript.jsonl, audit_log.json, pipecat_logs.jsonl)
  • ExternalAgentConfig base + TelnyxExternalAgentConfig subclass with discriminator

Adding a new provider

Only requires a new providers/xxx/ directory with config, transport, and setup. No changes to bridge, worker, runner, or metrics pipeline.

Backward compatibility

  • TelephonyBridgeConfig → alias for TelnyxExternalAgentConfig
  • TelephonyBridgeServer → alias for ExternalAgentBridgeServer
  • All old env vars (EVA_MODEL__SIP_URI, etc.) continue to work
  • Old import paths preserved as thin re-exports
  • Output format unchanged (pipecat_logs.jsonl filename kept for upstream metrics compat)

Context

Extract provider-agnostic bridge from Telnyx-specific implementation to
enable upstream EVA to support multiple hosted voice agent APIs
(ElevenLabs, Deepgram, OpenAI Realtime, etc.)

Architecture:
- New `eva.assistant.external` package with shared ABCs and generic bridge
- `ExternalAgentProvider` ABC: plugin interface for hosted voice APIs
  (create_transport, setup, teardown, fetch_intended_speech, webhook routes)
- `ExternalAgentBridgeServer`: provider-agnostic WebSocket bridge with
  audio routing, VAD observation, and output persistence
- `ExternalAgentConfig` base + `TelnyxExternalAgentConfig` subclass
- `TelnyxProvider`: concrete implementation with Call Control transport,
  assistant manager, DV webhooks, and Conversations API enrichment
- Provider factory: `get_provider(config)` with lazy-import registry
- Old module paths preserved as thin re-exports for backward compatibility
  (TelephonyBridgeConfig, TelephonyBridgeServer, etc.)

Adding a new provider requires only a new `providers/xxx/` directory
with config, transport, and setup — no changes to bridge, worker,
runner, or metrics pipeline.

Targets upstream roadmap item: 'Extended Leaderboard - native voice
agent APIs beyond Pipecat'
Old module paths now raise ImportError with migration guidance.
Tests updated to import directly from new locations.
No aliases (TelephonyBridgeConfig, TelephonyBridgeServer, etc.).
@jamestwhedbee jamestwhedbee marked this pull request as ready for review March 31, 2026 16:03
@jamestwhedbee jamestwhedbee merged commit ff701af into main Mar 31, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant