- Implementation of specialist execution api, including SSE protocol

- eveai_chat becomes deprecated and should be replaced with SSE
- Adaptation of STANDARD_RAG specialist
- Base class definition allowing to realise specialists with crewai framework
- Implementation of SPIN_SPECIALIST
- Implementation of test app for testing specialists (test_specialist_client). Also serves as an example for future SSE-based client
- Improvements to startup scripts to better handle and scale multiple connections
- Small improvements to the interaction forms and views
- Caching implementation improved and augmented with additional caches
This commit is contained in:
Josako
2025-02-20 05:50:16 +01:00
parent d106520d22
commit 25213f2004
79 changed files with 2791 additions and 347 deletions

View File

@@ -0,0 +1,75 @@
from typing import Dict, Any, Type
from flask import current_app
from common.utils.cache.base import CacheHandler
from common.utils.cache.crewai_configuration import SpecialistProcessedConfig
from common.utils.cache.crewai_config_processor import BaseCrewAIConfigProcessor
class CrewAIProcessedConfigCacheHandler(CacheHandler[SpecialistProcessedConfig]):
"""Handles caching of processed specialist configurations"""
handler_name = 'crewai_processed_config_cache'
def __init__(self, region):
super().__init__(region, 'crewai_processed_config')
self.configure_keys('tenant_id', 'specialist_id')
def _to_cache_data(self, instance: SpecialistProcessedConfig) -> Dict[str, Any]:
"""Convert SpecialistProcessedConfig to cache data"""
return instance.to_dict()
def _from_cache_data(self, data: Dict[str, Any], **kwargs) -> SpecialistProcessedConfig:
"""Create SpecialistProcessedConfig from cache data"""
return SpecialistProcessedConfig.from_dict(data)
def _should_cache(self, value: Dict[str, Any]) -> bool:
"""Validate cache data"""
required_keys = {'agents', 'tasks', 'tools'}
if not all(key in value for key in required_keys):
current_app.logger.warning(f'CrewAI Processed Config Cache missing required keys: {required_keys}')
return False
return bool(value['agents'] or value['tasks'])
def get_specialist_config(self, tenant_id: int, specialist_id: int) -> SpecialistProcessedConfig:
"""
Get or create processed configuration for a specialist
Args:
tenant_id: Tenant ID
specialist_id: Specialist ID
Returns:
Processed specialist configuration
Raises:
ValueError: If specialist not found or processor not configured
"""
def creator_func(tenant_id: int, specialist_id: int) -> SpecialistProcessedConfig:
# Create processor instance and process config
processor = BaseCrewAIConfigProcessor(tenant_id, specialist_id)
return processor.process_config()
return self.get(
creator_func,
tenant_id=tenant_id,
specialist_id=specialist_id
)
def invalidate_tenant_specialist(self, tenant_id: int, specialist_id: int):
"""Invalidate cache for a specific tenant's specialist"""
self.invalidate(
tenant_id=tenant_id,
specialist_id=specialist_id
)
current_app.logger.info(
f"Invalidated cache for tenant {tenant_id} specialist {specialist_id}"
)
def register_specialist_cache_handlers(cache_manager) -> None:
"""Register specialist cache handlers with cache manager"""
cache_manager.register_handler(
CrewAIProcessedConfigCacheHandler,
'eveai_chat_workers'
)