
    *"hj{!                    Z   d Z ddlmZ ddlZddlZddlmZmZ ddlm	Z	 ddl
mZmZmZmZ  ej                  e      ZddZddZdd	Zdd
ZddZddZddZddZ	 d	 	 	 	 	 	 	 ddZ	 d	 	 	 	 	 	 	 d dZd!dZd"dZd!dZ	 	 	 	 	 	 	 	 	 	 d#dZ	 	 	 	 	 	 	 	 d$dZ 	 d	 	 	 	 	 	 	 	 	 d%dZ!y)&z Shared storage helper functions.    )annotationsN)AnyOptionalbuild_object_store)bundle_entrypoint_textbundle_file_recordsbundle_tree_sha256coerce_skill_bundlec                "    t        d| |||      S )zBBackward-compatible helper that builds an OSS-backed object store.oss)backendendpointbucketaccess_key_idsecret_access_keyr   )r   bucket_namekey_id
key_secrets       </root/.hermes/SkillClaw/evolve_server/storage/oss_helpers.pymake_bucketr      s    $     c                B   t        | d      r| j                  | d      }n<ddlm}m} t        | |      r || | d      }nddl}|j                  | | d      }g }|D ]9  }|j                  j                  d      s|j                  |j                         ; |S )	z8List all ``*.json`` objects under ``{prefix}sessions/``.iter_objectsz	sessions/prefix   LocalBucketLocalObjectIteratorr   Nz.json)hasattrr   mock_bucketr   r    
isinstanceoss2ObjectIteratorkeyendswithappend)r   r   iteratorr   r    r$   keysobjs           r   list_session_keysr,      s    v~&&&	.B&CAfk**6VHI:NOH**6VHI:N*OHD !77G$KK ! Kr   c                    t        | d      r| j                  |      }n6ddlm}m} t        | |      r || |      }nddl}|j                  | |      }|D cg c]  }|j                   c}S c c}w )z>List all object keys under *prefix* across local/OSS backends.r   r   r   r   r   N)	r!   r   r"   r   r    r#   r$   r%   r&   )r   r   r)   r   r    r$   r+   s          r   list_object_keysr.   3   sh    v~&&&f&5Afk**6&AH**6&*AH'(CGG(((s   A0c                    	 | j                  |      j                         j                  d      }t        j                  |      S # t
        $ r!}t        j                  d||       Y d}~yd}~ww xY w)z5Download and parse a single JSON object from storage.utf-8z[Storage] failed to read %s: %sN)
get_objectreaddecodejsonloads	Exceptionloggerwarning)r   r&   dataes       r   read_json_objectr;   C   s^      %**,33G<zz$ 8#qAs   AA 	A/A**A/c                   | d}	 | j                  |      j                         j                  d      }i }|j	                         j                         D ]B  }|j	                         s	 t        j                  |      }|j                  dd      }|r|||<   D |S # t        $ r i cY S w xY w# t        j                  $ r Y mw xY w)zGLoad ``manifest.jsonl`` from storage. Returns ``{skill_name: record}``.manifest.jsonlr0   name )
r1   r2   r3   r6   strip
splitlinesr4   r5   getJSONDecodeError)r   r   r&   r9   skillslinerecr>   s           r   load_manifestrG   M   s    HN
#C  %**,33G< )+F

'') 	zz|	**T"C7762&D"t	 M  	 ## 		s#   .B *.B-B*)B*-CCc                    |j                         D cg c]  }t        j                  |d       }}|rdj                  |      dz   nd}| j	                  | d|j                  d             yc c}w )z(Write the full manifest back to storage.F)ensure_ascii
r?   r=   r0   N)valuesr4   dumpsjoin
put_objectencode)r   r   manifestrF   linescontents         r   save_manifestrS   c   sd    <DOO<MNSTZZ%0NEN).dii%BG
/1HI Os   A0c                    d}|D ]  }	 | j                  |       |dz  } |r t        j	                  d|t        |             |S # t        $ r!}t        j                  d||       Y d}~ed}~ww xY w)zqDelete session objects from the bucket (OSS or local).

    Returns the number of successfully deleted keys.
    r   r   z[OSS] failed to delete %s: %sNz [OSS] deleted %d/%d session keys)delete_objectr6   r7   r8   infolen)r   r*   deletedr&   r:   s        r   delete_session_keysrY   j   s~    
 G D	D  %qLGD 6TKN	  	DNN:CCC	Ds   A	A/A**A/c                    | d| d}	 | j                  |      j                         j                  d      S # t        $ r Y yw xY w)z,Download a single ``SKILL.md`` from storage.skills/	/SKILL.mdr0   N)r1   r2   r3   r6   )r   r   
skill_namer&   s       r   fetch_skill_contentr^   {   sP    HGJ<y
1C  %**,33G<< s   -8 	AAc                   i }|xs i j                  d      }t        |t              r|r|D ]  }t        |xs i j                  d      xs d      j	                         j                  dd      }|sF|dk(  r	| d| d}n
| d| d	| }| j                  |      j                         ||<    |S t        | ||      }	|	i S |	j                  d
      |d<   |S )zDownload a full skill bundle from storage.

    Backward compatibility:
      - bundle-aware records read nested files from ``skills/<name>/files/...``
      - legacy records fall back to a single ``SKILL.md``
    filespathr?   \/SKILL.mdr[   r\   z/files/r0   )
rB   r#   liststrr@   replacer1   r2   r^   rO   )
r   r   r]   recordbundlefile_entriesitemrel_pathr&   rR   s
             r   fetch_skill_bundlerm      s      "FLb%%g.L,%,  	=DDJB++F39r:@@BJJ4QTUH:%
|9=
|78*E%005::<F8	= !&&*=G	 0F:Mr   c                Z    t        | |||      }|sy	 t        |      S # t        $ r Y yw xY w)z@Download the bundle and return its ``SKILL.md`` entrypoint text.N)rm   r   r6   )r   r   r]   rh   ri   s        r   fetch_skill_bundle_textro      s<      
FCF%f-- s   
 	**c                F    |  d| dt        dt        |xs d             dS )Nr[   z/versions/vr   rc   )maxintr   r]   versions      r   skill_version_prefixru      s,    XWZLC3w|!;L4M3NaPPr   c                    t        |xs d      j                         j                  dd      }t        | ||      }|dk(  r| dS | d| S )Nr?   rb   rc   rd   files/)rf   r@   rg   ru   )r   r]   rt   rl   cleanbases         r   skill_version_bundle_keyrz      sZ    B%%'//c:E
G<D
x  V6%!!r   c                "    t        | ||       dS )Nzbundle.json)ru   rs   s      r   skill_version_record_keyr|      s    "6:w?@LLr   c                   t        |      }ddt        |      t        |      d}t               }t	        |j                               D ]6  \  }}	t        ||||      }
|j                  |
       | j                  |
|	       8 t        | t        |||       d      D ]  }
|
|vs| j                  |
        | j                  t        |||      t        j                  |dd      j                  d             |S )	N	bundle_v1rd   )format
entrypointtree_sha256r`   rw   F   )rI   indentr0   )r   r
   r	   setsorteditemsrz   addrN   r.   ru   rU   r|   r4   rL   rO   )r   r   r]   rt   bundle_filesri   rh   	keep_keysrl   r9   r&   s              r   save_version_bundler      s     !.F )&1$V,	F %I 0 %$&vz7HMc#t$%  +?
T[+\*]]c(de &i  %&  W=

6a8??H Mr   c                    	 | j                  t        |||            j                         j                  d      }t	        j
                  |      }t        |t              r|S d S # t        $ r Y y w xY w)Nr0   )	r1   r|   r2   r3   r4   r5   r#   dictr6   )r   r   r]   rt   payloadr9   s         r   load_version_bundle_recordr      sk    ##$<VZQX$YZ__ahhipqzz'"!$-t747 s   AA$ "A$ $	A0/A0c                   i }|xs t        | |||      xs i }|j                  d      }t        |t              r~|r||D ]u  }t	        |xs i j                  d      xs d      j                         j                  dd      }	|	sFt        ||||	      }
| j                  |
      j                         ||	<   w |S 	 | j                  t        |||d            j                         |d<   |S # t        $ r i cY S w xY w)Nr`   ra   r?   rb   rc   rd   )r   rB   r#   re   rf   r@   rg   rz   r1   r2   r6   )r   r   r]   rt   rh   ri   version_recordrj   rk   rl   r&   s              r   fetch_version_bundler      s     "Fd9&&*V]^dbdN!%%g.L,%,  	=DDJB++F39r:@@BJJ4QTUH*6:wQC%005::<F8	= #../GPZ\ceo/pqvvxz M  	s   9.C) )C76C7)r   rf   r   rf   r   rf   r   rf   )r   rf   return	list[str])r&   rf   r   zOptional[dict])r   rf   r   dict[str, dict[str, Any]])r   rf   rP   r   r   None)r*   r   r   rr   )r   rf   r]   rf   r   Optional[str])N)r   rf   r]   rf   rh   Optional[dict[str, Any]]r   dict[str, bytes])r   rf   r]   rf   rh   r   r   r   )r   rf   r]   rf   rt   rr   r   rf   )
r   rf   r]   rf   rt   rr   rl   rf   r   rf   )
r   rf   r]   rf   rt   rr   r   r   r   zdict[str, Any])r   rf   r]   rf   rt   rr   r   r   )
r   rf   r]   rf   rt   rr   rh   r   r   r   )"__doc__
__future__r   r4   loggingtypingr   r   skillclaw.object_storer   skillclaw.skill_bundler   r	   r
   r   	getLogger__name__r7   r   r,   r.   r;   rG   rS   rY   r^   rm   ro   ru   rz   r|   r   r   r    r   r   <module>r      sj   & "     5  
		8	$() ,J" (,	  %	
 J (,	  %	
  Q"M  	
 # :  	
 & (,  	
 % r   