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(