
    iJ                         d Z ddlmZmZmZ ddlmZmZ ddlZddl	Z		 ddl
mZ dZdefdZ e       Ze G d	 d
             Z G d d      Zy# e$ r 	 ddlZdZn# e$ r dZY nw xY wY Cw xY w)u   
Genesis Persistent Context Architecture — Redis L1 Working State
Story 2.01 — Track B

Typed Redis L1 schema with versioned state operations.
All agents read/write task state in consistent, OCC-safe format.
    )	dataclassasdictfield)OptionalListNTFreturnc                      t        j                  d      } | r| S t        j                  dd      }t        j                  dd      }t        j                  dd      }d| d	| d
| S )zEBuild Redis URL from env vars, preferring individual config over URL.	REDIS_URLGENESIS_REDIS_HOSTz#redis-genesis-u50607.vm.elestio.appGENESIS_REDIS_PORT26379GENESIS_REDIS_PASSWORDze2ZyYYr4oWRdASI2CaLc-zredis://default:@:)osgetenv)urlhostportpasswords       4/mnt/e/genesis-system/core/memory/redis_l1_schema.py_build_default_redis_urlr      sh     ))K
 C

99)+PQD99)73Dyy13JKHhZqav66    c                       e Zd ZU dZeed<   eed<   eed<    ee      Ze	e   ed<   dZ
eed<    ee      Ze	e   ed	<   d
Zee   ed<   dZeed<   y
)RedisL1Statez'Working state stored in Redis L1 cache.task_id
session_idactive_task_id)default_factoryfocus_entities current_hypothesisexhausted_pathsNactive_blockerr   version)__name__
__module____qualname____doc__str__annotations__r   listr    r   r"   r#   r$   r   r%   int r   r   r   r   (   s^    1LO %d ;NDI;  !&t!<OT#Y<$(NHSM(GSr   r   c                       e Zd ZdZdZddefdZd Zdedefd	Zdede	e
   fd
Zdde
dedefdZdedefdZdedefdZd Zy)RedisL1Clientz5Client for reading/writing L1 working state to Redis.zgenesis:state:task:N	redis_urlc                 0    |xs t         | _        d | _        y N)r
   _url_redis)selfr1   s     r   __init__zRedisL1Client.__init__9   s    *	r   c                    K   | j                   Ct        r2t        j                  | j                  d      | _         | j                   S t        d      | j                   S w)NT)decode_responseszredis.asyncio not available)r5   ASYNC_REDISaioredisfrom_urlr4   ImportErrorr6   s    r   
_get_rediszRedisL1Client._get_redis=   sO     ;;&//		DQ {{ ""?@@{{s   AAr   r   c                 "    | j                    | S r3   )
KEY_PREFIX)r6   r   s     r   _keyzRedisL1Client._keyE   s    //"7),,r   c                 ~  K   | j                          d{   }|j                  | j                  |             d{   }|sy	 t        |t              rt        j                  |      n"t        j                  |j                               }t        di |S 7 7 ]# t
        j                  t        f$ r Y yw xY ww)z`
        Get working state for a task.
        Returns None on cache miss (cold start).
        Nr.   )r?   getrB   
isinstancer*   jsonloadsdecoder   JSONDecodeError	TypeError)r6   r   rrawdatas        r   	get_statezRedisL1Client.get_stateH   s     
 //##EE$))G,--	&0c&:4::c?

3::<@XD'$'' $- $$i0 		sD   B=B'B=BB=AB B=B=B:7B=9B::B=statettl_secondsc                    K   | j                          d{   }| j                  |j                        }t        j                  t        |            }|j                  |||       d{   }t        |      S 7 c7 w)zY
        Write working state with TTL.
        Uses SETEX for atomic set+expire.
        N)r?   rB   r   rF   dumpsr   setexbool)r6   rO   rP   rK   keyrM   results          r   	set_statezRedisL1Client.set_stateW   se     
 //##ii&zz&-(wwsK66F|	 $ 7s"   A>A:AA>*A<+A><A>c                    K   | j                          d{   }| j                  |       d}|j                  |       d{   }|S 7 37 w)z
        Atomically increment version counter.
        Uses Redis INCR (not read-modify-write).
        Returns new version number.
        Nz:version)r?   rB   incr)r6   r   rK   version_keynew_versions        r   bump_versionzRedisL1Client.bump_versionb   sO      //##7+,H5FF;//	 $ 0s!   AA
,AAAAc                    K   | j                          d{   }|j                  | j                  |             d{   }t        |      S 7 77 w)z"Delete state for a task (cleanup).N)r?   deleterB   rT   )r6   r   rK   rV   s       r   delete_statezRedisL1Client.delete_staten   sB     //##xx		' 233F| $3s   AA'AAAAc                 |   K   | j                   r*| j                   j                          d{    d| _         yy7 w)zClose Redis connection.N)r5   closer>   s    r   ra   zRedisL1Client.closet   s2     ;;++##%%%DK %s   *<:<r3   )i  )r&   r'   r(   r)   rA   r*   r7   r?   rB   r   r   rN   r-   rT   rW   r\   r_   ra   r.   r   r   r0   r0   5   s    ?&J# -C -C -s x/E 	\ 	 	t 	
# 
# 
# $ r   r0   )r)   dataclassesr   r   r   typingr   r   rF   r   redis.asyncioasyncior;   r:   r=   redis
sync_redisr*   r   r
   r   r0   r.   r   r   <module>rh      s    1 0 !  	$K
7# 
7 %&	 	 	 	C CI  " 	s5   A A*AA*A$!A*#A$$A*)A*