Skip to content

Reliability: wire the Temporal voice provider (pipecat_provider) end-to-end #6

Description

@teetangh

Context

The Temporal production path (apps/worker/activities.pyresolve_via_voiceget_voice_provider()) selects PipecatProvider (apps/voice/pipecat_provider.py) per settings.yaml (voice.provider: pipecat) — but that provider is a non-functional scaffold:

  • _LiveTranscriptCapture.process_frame is a ... no-op (lines 148-152) — transcripts stay empty, breaking the cross-modal HandoffContext claim.
  • _classify_outcome relies on the LLM literally saying "deal agreed" in text (the streaming module long since moved to end_call tool calls).
  • recording_url and cost_usd are hardcoded placeholders (cost_usd=0.0 at line 102).
  • It references a TwilioTransport import that doesn't match the shipped Pipecat 1.x API.

Meanwhile the real, working pipeline lives in apps/voice/streaming.py behind the FastAPI WS endpoint.

Implementation plan

  1. Reuse, don't duplicate: refactor pipecat_provider.py to drive the existing HTTP flow — call POST /voice/streaming/dial-init, place the call, then await the session result — rather than constructing a second Pipecat pipeline. Extract shared session-result plumbing (outcome, transcript, cost) into apps/voice/session_result.py.
  2. Transcript capture: in the streaming pipeline, subscribe to TranscriptProcessor (or aggregate TranscriptionFrame / assistant TextFrames via the existing context aggregator) and persist turn-by-turn transcript on the session record.
  3. Outcome from tools: session outcome comes from the end_call(outcome=...) tool args (handle_end_call, streaming.py:537-548) — expose it on the session result; delete _classify_outcome text matching.
  4. Recording URL: capture from Twilio's recording status callback (call placed with record=True) and attach to the session result.
  5. Cost: take total_cost_usd from the P0 VoiceCallMetricsObserver summary instead of 0.0.
  6. Borrower phone lookup: replace BORROWER_PHONE__{id} env vars (pipecat_provider.py:110-124) with a proper lookup (settings/DB), keeping the env override for dev.
  7. Tests: activity-level test with the mock provider still green; integration smoke running the Temporal workflow against the simulator-backed streaming endpoint with populated transcript/outcome/cost.

Acceptance criteria

  • CollectionsWorkflow completes end-to-end with voice.provider: pipecat against the simulator: non-empty transcript, outcome sourced from the end_call tool, non-zero cost_usd, recording URL populated on real calls.
  • No duplicate pipeline-construction code between pipecat_provider.py and streaming.py.

Dependencies

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium priorityenhancementNew feature or requestreliabilityReliability, scaling, and session durability

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions