feat(P01-03-03,P01-03-07): Pipecat Flows wiring + scenario-driven prompt
server/scenarios/runtime.py — ScenarioRuntime maps a Scenario to a Pipecat Flows state-machine spec: initial 'conversation' state with the scenario's system prompt + opening line, branch metadata carried in the spec (v0.1 has no in-flight transitions per G-002 — branching is post-hoc; Phase 2+ can fork without schema change). set_branch() resolves the branch outcome from the classifier; debrief_focus() returns the per-branch focus. TASK-03-07: server/pipeline.py build_pipeline() now accepts a scenario_id, loads the runtime, and uses scenario.setup.system_prompt instead of the SLICE-02 hardcoded walking-skeleton prompt. Falls back gracefully if the scenario can't load. server/__main__.py passes PRAXIS_SCENARIO=customer_service_refund_ca_v01 by default. 7 runtime tests pass (system prompt, set_branch accept/escalate, unknown-branch error, debrief_focus per branch, flows spec branches, debrief model config). ---ci--- phase: 1 milestone: v0.1 plan: 03 task: 03-03,03-07 status: execute persona: backend-engineer requirements: covered: [REQ-SCEN-01, REQ-SCEN-FMT-01, REQ-ORCH-02] ---/ci---
This commit is contained in:
+16
-2
@@ -75,7 +75,12 @@ async def health() -> dict[str, Any]:
|
||||
|
||||
@app.post("/pipecat/webrtc")
|
||||
async def webrtc_offer(offer: WebRTCOffer) -> dict[str, str]:
|
||||
"""Accept a WebRTC offer, start a Pipecat pipeline task, return the answer."""
|
||||
"""Accept a WebRTC offer, start a Pipecat pipeline task, return the answer.
|
||||
|
||||
Loads the v0.1 scenario (customer_service_refund_ca_v01) so the pipeline
|
||||
uses the scenario-driven system prompt + opening line (TASK-03-07).
|
||||
"""
|
||||
scenario_id = _env("PRAXIS_SCENARIO", "customer_service_refund_ca_v01")
|
||||
try:
|
||||
connection = SmallWebRTCConnection(
|
||||
ice_servers=[{"urls": "stun:stun.l.google.com:19302"}],
|
||||
@@ -84,11 +89,20 @@ async def webrtc_offer(offer: WebRTCOffer) -> dict[str, str]:
|
||||
await connection.accept()
|
||||
answer = connection.get_answer()
|
||||
# Build + run the pipeline for this connection.
|
||||
pipeline, task, runner, transport = build_pipeline(connection)
|
||||
pipeline, task, runner, transport, scenario_runtime = build_pipeline(
|
||||
connection, scenario_id=scenario_id
|
||||
)
|
||||
# Run the pipeline task in the background; the runner manages its lifecycle.
|
||||
import asyncio
|
||||
|
||||
asyncio.create_task(runner.run(task))
|
||||
# Play the opening line + disclaimer as the first AI utterance if the
|
||||
# scenario loaded (the runner handles the actual TTS queueing).
|
||||
if scenario_runtime is not None:
|
||||
logger.info(
|
||||
f"Session starting with scenario {scenario_id!r}; "
|
||||
f"opening line: {scenario_runtime.opening_line[:60]!r}"
|
||||
)
|
||||
return {"sdp": answer["sdp"], "type": answer["type"]}
|
||||
except Exception as exc:
|
||||
logger.error(f"WebRTC offer failed: {exc}")
|
||||
|
||||
Reference in New Issue
Block a user