feat: add logs in campaigns for failure or pausing (#265)

* feat: add logs in campaigns on failure

* chore: bump pipecat

* chore: update format.sh

* chore: fix github workflow

* fix: fix formatting errors
This commit is contained in:
Abhishek 2026-05-05 19:23:50 +05:30 committed by GitHub
parent abfb678b4d
commit d4b6afb020
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
77 changed files with 1001 additions and 245 deletions

View file

@ -17,13 +17,13 @@ from typing import Optional
from fastapi import APIRouter, WebSocket
from loguru import logger
from pipecat.utils.run_context import set_current_org_id, set_current_run_id
from starlette.websockets import WebSocketDisconnect
from api.db import db_client
from api.enums import CallType, WorkflowRunState
from api.services.quota_service import check_dograh_quota_by_user_id
from api.services.telephony import registry as telephony_registry
from pipecat.utils.run_context import set_current_org_id, set_current_run_id
router = APIRouter(prefix="/agent-stream")

View file

@ -1,6 +1,6 @@
import json
from datetime import datetime
from typing import List, Optional
from typing import Any, Dict, List, Optional
from zoneinfo import ZoneInfo
from fastapi import APIRouter, Depends, HTTPException, Query
@ -172,6 +172,20 @@ class UpdateCampaignRequest(BaseModel):
circuit_breaker: Optional[CircuitBreakerConfigRequest] = None
class CampaignLogEntryResponse(BaseModel):
"""A single timestamped entry from the campaign's append-only log.
Surfaced in the UI so operators can see why a campaign moved to
paused / failed without digging through server logs.
"""
ts: str
level: str
event: str
message: str
details: Optional[Dict[str, Any]] = None
class CampaignResponse(BaseModel):
id: int
name: str
@ -196,6 +210,7 @@ class CampaignResponse(BaseModel):
redialed_campaign_id: Optional[int] = None
telephony_configuration_id: Optional[int] = None
telephony_configuration_name: Optional[str] = None
logs: List[CampaignLogEntryResponse] = Field(default_factory=list)
class CampaignsResponse(BaseModel):
@ -298,6 +313,11 @@ def _build_campaign_response(
redialed_campaign_id=redialed_campaign_id,
telephony_configuration_id=campaign.telephony_configuration_id,
telephony_configuration_name=telephony_configuration_name,
logs=[
CampaignLogEntryResponse(**entry)
for entry in (campaign.logs or [])
if isinstance(entry, dict)
],
)

View file

@ -15,7 +15,6 @@ from fastapi import (
WebSocket,
)
from loguru import logger
from pipecat.utils.run_context import set_current_run_id
from pydantic import BaseModel, field_validator
from starlette.websockets import WebSocketDisconnect
@ -45,6 +44,7 @@ from api.utils.telephony_helper import (
numbers_match,
parse_webhook_request,
)
from pipecat.utils.run_context import set_current_run_id
router = APIRouter(prefix="/telephony")

View file

@ -24,8 +24,6 @@ from aiortc import RTCIceServer
from aiortc.sdp import candidate_from_sdp
from fastapi import APIRouter, Depends, HTTPException, WebSocket, WebSocketDisconnect
from loguru import logger
from pipecat.transports.smallwebrtc.connection import SmallWebRTCConnection
from pipecat.utils.run_context import set_current_org_id, set_current_run_id
from starlette.websockets import WebSocketState
from api.constants import ENVIRONMENT
@ -45,6 +43,8 @@ from api.services.pipecat.ws_sender_registry import (
unregister_ws_sender,
)
from api.services.quota_service import check_dograh_quota
from pipecat.transports.smallwebrtc.connection import SmallWebRTCConnection
from pipecat.utils.run_context import set_current_org_id, set_current_run_id
router = APIRouter(prefix="/ws")