@ -1,6 +1,7 @@
from datetime import datetime , timedelta
from datetime import datetime , timedelta
from app. core . time_utils import utc_now
from threading import RLock
from app . core . time_utils import utc_now
from app . services . orchestration . conversation_state_repository import ConversationStateRepository
from app . services . orchestration . conversation_state_repository import ConversationStateRepository
@ -8,6 +9,7 @@ from app.services.orchestration.conversation_state_repository import Conversatio
# Serve como fallback simples para desenvolvimento e testes.
# Serve como fallback simples para desenvolvimento e testes.
class ConversationStateStore ( ConversationStateRepository ) :
class ConversationStateStore ( ConversationStateRepository ) :
def __init__ ( self ) - > None :
def __init__ ( self ) - > None :
self . _lock = RLock ( )
self . user_contexts : dict [ int , dict ] = { }
self . user_contexts : dict [ int , dict ] = { }
self . pending_review_confirmations : dict [ int , dict ] = { }
self . pending_review_confirmations : dict [ int , dict ] = { }
self . pending_review_drafts : dict [ int , dict ] = { }
self . pending_review_drafts : dict [ int , dict ] = { }
@ -20,68 +22,74 @@ class ConversationStateStore(ConversationStateRepository):
self . pending_rental_drafts : dict [ int , dict ] = { }
self . pending_rental_drafts : dict [ int , dict ] = { }
self . pending_rental_selections : dict [ int , dict ] = { }
self . pending_rental_selections : dict [ int , dict ] = { }
self . telegram_processed_messages : dict [ int , dict ] = { }
self . telegram_processed_messages : dict [ int , dict ] = { }
self . telegram_runtime_state : dict [ int , dict ] = { }
def upsert_user_context ( self , user_id : int | None , ttl_minutes : int ) - > None :
def upsert_user_context ( self , user_id : int | None , ttl_minutes : int ) - > None :
if user_id is None :
if user_id is None :
return
return
now = utc_now ( )
with self . _lock :
context = self . user_contexts . get ( user_id )
now = utc_now ( )
if context and context [ " expires_at " ] > = now :
context = self . user_contexts . get ( user_id )
context [ " expires_at " ] = now + timedelta ( minutes = ttl_minutes )
if context and context [ " expires_at " ] > = now :
return
context [ " expires_at " ] = now + timedelta ( minutes = ttl_minutes )
self . user_contexts [ user_id ] = {
return
" active_domain " : " general " ,
self . user_contexts [ user_id ] = {
" active_task " : None ,
" active_domain " : " general " ,
" generic_memory " : { } ,
" active_task " : None ,
" shared_memory " : { } ,
" generic_memory " : { } ,
" collected_slots " : { } ,
" shared_memory " : { } ,
" flow_snapshots " : { } ,
" collected_slots " : { } ,
" last_tool_result " : None ,
" flow_snapshots " : { } ,
" order_queue " : [ ] ,
" last_tool_result " : None ,
" pending_order_selection " : None ,
" order_queue " : [ ] ,
" pending_switch " : None ,
" pending_order_selection " : None ,
" last_stock_results " : [ ] ,
" pending_switch " : None ,
" selected_vehicle " : None ,
" last_stock_results " : [ ] ,
" last_rental_results " : [ ] ,
" selected_vehicle " : None ,
" selected_rental_vehicle " : None ,
" last_rental_results " : [ ] ,
" expires_at " : now + timedelta ( minutes = ttl_minutes ) ,
" selected_rental_vehicle " : None ,
}
" expires_at " : now + timedelta ( minutes = ttl_minutes ) ,
}
def get_user_context ( self , user_id : int | None ) - > dict | None :
def get_user_context ( self , user_id : int | None ) - > dict | None :
if user_id is None :
if user_id is None :
return None
return None
context = self . user_contexts . get ( user_id )
with self . _lock :
if not context :
context = self . user_contexts . get ( user_id )
return None
if not context :
if context [ " expires_at " ] < utc_now ( ) :
return None
self . user_contexts . pop ( user_id , None )
if context [ " expires_at " ] < utc_now ( ) :
return None
self . user_contexts . pop ( user_id , None )
return context
return None
return context
def save_user_context ( self , user_id : int | None , context : dict ) - > None :
def save_user_context ( self , user_id : int | None , context : dict ) - > None :
if user_id is None or not isinstance ( context , dict ) :
if user_id is None or not isinstance ( context , dict ) :
return
return
self . user_contexts [ user_id ] = context
with self . _lock :
self . user_contexts [ user_id ] = context
def get_entry ( self , bucket : str , user_id : int | None , * , expire : bool = False ) - > dict | None :
def get_entry ( self , bucket : str , user_id : int | None , * , expire : bool = False ) - > dict | None :
if user_id is None :
if user_id is None :
return None
return None
entries = getattr ( self , bucket )
with self . _lock :
entry = entries . get ( user_id )
entries = getattr ( self , bucket )
if not entry :
entry = entries . get ( user_id )
return None
if not entry :
if expire and entry . get ( " expires_at " ) and entry [ " expires_at " ] < utc_now ( ) :
return None
entries . pop ( user_id , None )
if expire and entry . get ( " expires_at " ) and entry [ " expires_at " ] < utc_now ( ) :
return None
entries . pop ( user_id , None )
return entry
return None
return entry
def set_entry ( self , bucket : str , user_id : int | None , value : dict ) - > None :
def set_entry ( self , bucket : str , user_id : int | None , value : dict ) - > None :
if user_id is None :
if user_id is None :
return
return
getattr ( self , bucket ) [ user_id ] = value
with self . _lock :
getattr ( self , bucket ) [ user_id ] = value
def pop_entry ( self , bucket : str , user_id : int | None ) - > dict | None :
def pop_entry ( self , bucket : str , user_id : int | None ) - > dict | None :
if user_id is None :
if user_id is None :
return None
return None
return getattr ( self , bucket ) . pop ( user_id , None )
with self . _lock :
return getattr ( self , bucket ) . pop ( user_id , None )