bug:service center

This commit is contained in:
Ida Dittrich 2026-03-09 10:49:15 +01:00
parent d59c6c8576
commit d7636d72c4
5 changed files with 25 additions and 9 deletions

View file

@ -129,6 +129,7 @@ REQUIRED_SERVICES = [
{"serviceKey": "billing", "meta": {"usage": "AI call billing"}}, {"serviceKey": "billing", "meta": {"usage": "AI call billing"}},
{"serviceKey": "extraction", "meta": {"usage": "Workflow method actions"}}, {"serviceKey": "extraction", "meta": {"usage": "Workflow method actions"}},
{"serviceKey": "sharepoint", "meta": {"usage": "SharePoint actions (listDocuments, uploadDocument, etc.)"}}, {"serviceKey": "sharepoint", "meta": {"usage": "SharePoint actions (listDocuments, uploadDocument, etc.)"}},
{"serviceKey": "generation", "meta": {"usage": "Action completion messages, document creation from results"}},
] ]
@ -158,7 +159,8 @@ def getAutomationServices(
_workflow = workflow _workflow = workflow
if _workflow is None: if _workflow is None:
_workflow = type("_Placeholder", (), {"featureCode": FEATURE_CODE})() # Placeholder must have 'id' and 'workflowMode' to avoid AttributeError when services use context.workflow
_workflow = type("_Placeholder", (), {"featureCode": FEATURE_CODE, "id": None, "workflowMode": None})()
ctx = ServiceCenterContext( ctx = ServiceCenterContext(
user=user, user=user,
mandate_id=mandateId, mandate_id=mandateId,
@ -170,6 +172,7 @@ def getAutomationServices(
hub.user = user hub.user = user
hub.mandateId = mandateId hub.mandateId = mandateId
hub.featureInstanceId = featureInstanceId hub.featureInstanceId = featureInstanceId
hub._service_context = ctx # Store context so workflow updates propagate to services
hub.workflow = workflow hub.workflow = workflow
hub.featureCode = FEATURE_CODE hub.featureCode = FEATURE_CODE
hub.allowedProviders = None hub.allowedProviders = None
@ -206,6 +209,7 @@ class _AutomationServiceHub:
user = None user = None
mandateId = None mandateId = None
featureInstanceId = None featureInstanceId = None
_service_context = None # ServiceCenterContext; when workflow is set, context.workflow is updated
workflow = None workflow = None
featureCode = "automation" featureCode = "automation"
allowedProviders = None allowedProviders = None

View file

@ -57,6 +57,7 @@ REQUIRED_SERVICES = [
{"serviceKey": "billing", "meta": {"usage": "AI call billing"}}, {"serviceKey": "billing", "meta": {"usage": "AI call billing"}},
{"serviceKey": "extraction", "meta": {"usage": "Workflow method actions"}}, {"serviceKey": "extraction", "meta": {"usage": "Workflow method actions"}},
{"serviceKey": "sharepoint", "meta": {"usage": "SharePoint actions (listDocuments, uploadDocument, etc.)"}}, {"serviceKey": "sharepoint", "meta": {"usage": "SharePoint actions (listDocuments, uploadDocument, etc.)"}},
{"serviceKey": "generation", "meta": {"usage": "Action completion messages, document creation from results"}},
] ]
# Template roles for this feature # Template roles for this feature
# Role names MUST follow convention: {featureCode}-{roleName} # Role names MUST follow convention: {featureCode}-{roleName}

View file

@ -31,15 +31,18 @@ AiCallRequest.model_rebuild()
class _ServicesAdapter: class _ServicesAdapter:
"""Adapter providing Services-like interface from (context, get_service).""" """Adapter providing Services-like interface from (context, get_service).
Workflow is read from context dynamically so propagation updates are visible."""
def __init__(self, context, get_service: Callable[[str], Any]): def __init__(self, context, get_service: Callable[[str], Any]):
self._context = context self._context = context
self._get_service = get_service self._get_service = get_service
self.user = context.user self.user = context.user
self.mandateId = context.mandate_id self.mandateId = context.mandate_id
self.featureInstanceId = context.feature_instance_id self.featureInstanceId = context.feature_instance_id
self.workflow = context.workflow
@property
def workflow(self):
return self._context.workflow
@property @property
def chat(self): def chat(self):

View file

@ -19,19 +19,22 @@ logger = logging.getLogger(__name__)
class _ServicesAdapter: class _ServicesAdapter:
"""Adapter providing Services-like interface from (context, get_service).""" """Adapter providing Services-like interface from (context, get_service).
Workflow is read from context dynamically so propagation updates are visible."""
def __init__(self, context, get_service: Callable[[str], Any]): def __init__(self, context, get_service: Callable[[str], Any]):
self._context = context self._context = context
self._get_service = get_service self._get_service = get_service
self.user = context.user self.user = context.user
self.mandateId = context.mandate_id self.mandateId = context.mandate_id
self.featureInstanceId = context.feature_instance_id self.featureInstanceId = context.feature_instance_id
self.workflow = context.workflow
chat = get_service("chat") chat = get_service("chat")
self.interfaceDbComponent = chat.interfaceDbComponent self.interfaceDbComponent = chat.interfaceDbComponent
self.interfaceDbChat = chat.interfaceDbChat self.interfaceDbChat = chat.interfaceDbChat
@property
def workflow(self):
return self._context.workflow
@property @property
def chat(self): def chat(self):
return self._get_service("chat") return self._get_service("chat")

View file

@ -27,9 +27,14 @@ class WorkflowProcessor:
def __init__(self, services): def __init__(self, services):
self.services = services self.services = services
self.mode = self._createMode(services.workflow.workflowMode)
self.mode.processor = self # So mode can call persistTaskResult for per-action chaining
self.workflow = services.workflow self.workflow = services.workflow
if not self.workflow:
raise ValueError("WorkflowProcessor requires services.workflow (set by WorkflowManager before processing)")
workflowMode = getattr(self.workflow, 'workflowMode', None)
if not workflowMode:
raise ValueError("WorkflowProcessor requires services.workflow.workflowMode")
self.mode = self._createMode(workflowMode)
self.mode.processor = self # So mode can call persistTaskResult for per-action chaining
self.workflowExecOperationId = None # Will be set by workflowManager for task hierarchy self.workflowExecOperationId = None # Will be set by workflowManager for task hierarchy
def _createMode(self, workflowMode: WorkflowModeEnum) -> BaseMode: def _createMode(self, workflowMode: WorkflowModeEnum) -> BaseMode: