from __future__ import annotations from dataclasses import dataclass, field from typing import Any, Dict, Optional from backend.llm.gateway import ModelGateway @dataclass class WorkflowState: prompt: str session_id: Optional[str] = None project_id: Optional[str] = None intent: str = "general" response: str = "" provider: Optional[str] = None model: Optional[str] = None metadata: Dict[str, Any] = field(default_factory=dict) class WorkflowEngine: """ Application workflow boundary. The workflow does not import provider implementations directly. All model execution goes through ModelGateway. """ def __init__( self, gateway: Optional[ModelGateway] = None, **gateway_kwargs: Any, ) -> None: self.gateway = gateway or ModelGateway(**gateway_kwargs) async def run( self, prompt: str, intent: str = "general", **kwargs: Any, ) -> WorkflowState: if not isinstance(prompt, str) or not prompt.strip(): raise ValueError("prompt must be a non-empty string") state = WorkflowState( prompt=prompt, intent=intent or "general", ) result = await self.gateway.complete( prompt=prompt, intent=state.intent, **kwargs, ) if isinstance(result, str): state.response = result elif isinstance(result, dict): state.response = str( result.get("text") or result.get("content") or result.get("response") or "" ) state.provider = result.get("provider") state.model = result.get("model") state.metadata.update(result) else: state.response = str(result) return state