From d88bacc4a91abcbbfc51421e0be69fa9e2b1221f Mon Sep 17 00:00:00 2001 From: patrick-motsch Date: Fri, 13 Feb 2026 14:43:45 +0100 Subject: [PATCH] billing fix --- .../features/teamsbot/routeFeatureTeamsbot.py | 12 ++++++--- modules/features/teamsbot/service.py | 25 ++++++++++++++++--- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/modules/features/teamsbot/routeFeatureTeamsbot.py b/modules/features/teamsbot/routeFeatureTeamsbot.py index 17e81dd3..258c535c 100644 --- a/modules/features/teamsbot/routeFeatureTeamsbot.py +++ b/modules/features/teamsbot/routeFeatureTeamsbot.py @@ -412,9 +412,15 @@ async def bridgeAudioWebsocket( logger.info(f"Bridge audio WebSocket config loaded: session={sessionId}") from modules.datamodels.datamodelUam import User - systemUser = User(id="system", username="system", email="p.motsch@poweron.swiss") - service = TeamsbotService(systemUser, None, instanceId, config) - logger.info(f"Bridge audio WebSocket service created: session={sessionId}") + systemUser = User(id="system", username="system", email="system@internal.local") + + # Look up mandateId from the session record (needed for AI billing context) + sessionInterface = interfaceDb.getInterface(systemUser, featureInstanceId=instanceId) + session = sessionInterface.getSession(sessionId) + mandateId = session.get("mandateId") if session else None + + service = TeamsbotService(systemUser, mandateId, instanceId, config) + logger.info(f"Bridge audio WebSocket service created: session={sessionId}, mandateId={mandateId}") await service.handleAudioStream(websocket, sessionId) except WebSocketDisconnect: diff --git a/modules/features/teamsbot/service.py b/modules/features/teamsbot/service.py index a3d9bef6..813edf44 100644 --- a/modules/features/teamsbot/service.py +++ b/modules/features/teamsbot/service.py @@ -31,6 +31,22 @@ from .bridgeConnector import BridgeConnector logger = logging.getLogger(__name__) + +# ========================================================================= +# Minimal Service Context (for AI billing in bridge callbacks) +# ========================================================================= + +class _ServiceContext: + """Minimal context providing user/mandate info for AiService billing. + Used by bridge callbacks where a full Services instance is not available.""" + + def __init__(self, user, mandateId, featureInstanceId=None): + self.user = user + self.mandateId = mandateId + self.featureInstanceId = featureInstanceId + self.featureCode = "teamsbot" + + # ========================================================================= # Session Event Queues (for SSE streaming to frontend) # ========================================================================= @@ -377,9 +393,9 @@ class TeamsbotService: try: from modules.services.serviceAi.mainServiceAi import AiService - # Create AiService with service center context - # Note: In production, serviceCenter should be passed properly - aiService = AiService(serviceCenter=None) + # Create minimal service context for AI billing + serviceContext = _ServiceContext(self.currentUser, self.mandateId, self.instanceId) + aiService = AiService(serviceCenter=serviceContext) await aiService.ensureAiObjectsInitialized() request = AiCallRequest( @@ -528,7 +544,8 @@ class TeamsbotService: from modules.services.serviceAi.mainServiceAi import AiService - aiService = AiService(serviceCenter=None) + serviceContext = _ServiceContext(self.currentUser, self.mandateId, self.instanceId) + aiService = AiService(serviceCenter=serviceContext) await aiService.ensureAiObjectsInitialized() request = AiCallRequest(