2023-09-11 00:46:56 +08:00
import os
2023-09-13 17:55:27 +08:00
2023-10-19 10:05:08 +08:00
from .object import ObjectStore , ObjectRelationStore , ObjectID , ObjectType , KnowledgeObject , DocumentObject , ImageObject , VideoObject , RichTextObject , EmailObject
from core_object import DocumentObject , ImageObject , VideoObject , RichTextObject , EmailObject
2023-09-11 20:32:52 +08:00
from .data import ChunkStore , ChunkTracker , ChunkListWriter , ChunkReader
2023-10-19 10:05:08 +08:00
import json
2023-09-11 00:46:56 +08:00
import logging
2023-09-26 00:39:27 +08:00
2023-09-11 00:46:56 +08:00
2023-10-18 11:19:11 -07:00
2023-09-11 02:05:24 +08:00
# KnowledgeStore class, which aggregates ChunkStore, ChunkTracker, and ObjectStore, and is a global singleton that makes it easy to use these three built-in store examples
2023-09-11 00:46:56 +08:00
class KnowledgeStore :
_instance = None
def __new__ ( cls ):
if cls . _instance is None :
cls . _instance = super () . __new__ ( cls )
2023-09-26 00:39:27 +08:00
import aios_kernel
2023-10-19 10:05:08 +08:00
knowledge_dir = aios_kernel . storage . AIStorage () . get_myai_dir () / "knowledge" / "objects"
2023-09-11 00:46:56 +08:00
2023-09-21 18:32:17 +08:00
if not os . path . exists ( knowledge_dir ):
os . makedirs ( knowledge_dir )
2023-09-11 00:46:56 +08:00
2023-09-21 18:32:17 +08:00
cls . _instance . __singleton_init__ ( knowledge_dir )
2023-09-11 00:46:56 +08:00
return cls . _instance
def __singleton_init__ ( self , root_dir : str ):
logging . info ( f "will init knowledge store, root_dir= { root_dir } " )
self . root = root_dir
2023-09-13 17:55:27 +08:00
relation_store_dir = os . path . join ( root_dir , "relation" )
self . relation_store = ObjectRelationStore ( relation_store_dir )
2023-09-11 00:46:56 +08:00
object_store_dir = os . path . join ( root_dir , "object" )
self . object_store = ObjectStore ( object_store_dir )
chunk_store_dir = os . path . join ( root_dir , "chunk" )
self . chunk_store = ChunkStore ( chunk_store_dir )
self . chunk_tracker = ChunkTracker ( chunk_store_dir )
2023-09-11 20:32:52 +08:00
self . chunk_list_writer = ChunkListWriter ( self . chunk_store , self . chunk_tracker )
self . chunk_reader = ChunkReader ( self . chunk_store , self . chunk_tracker )
2023-10-18 11:19:11 -07:00
2023-09-13 17:55:27 +08:00
def get_relation_store ( self ) -> ObjectRelationStore :
return self . relation_store
2023-09-11 00:46:56 +08:00
def get_object_store ( self ) -> ObjectStore :
return self . object_store
def get_chunk_store ( self ) -> ChunkStore :
return self . chunk_store
def get_chunk_tracker ( self ) -> ChunkTracker :
return self . chunk_tracker
2023-09-11 20:32:52 +08:00
def get_chunk_list_writer ( self ) -> ChunkListWriter :
return self . chunk_list_writer
def get_chunk_reader ( self ) -> ChunkReader :
return self . chunk_reader
2023-09-12 15:28:59 +08:00
2023-10-19 10:05:08 +08:00
async def insert_object ( self , object : KnowledgeObject ):
self . object_store . put_object ( object . calculate_id (), object . encode ())
def load_object ( self , object_id : ObjectID ) -> KnowledgeObject :
if object_id . get_object_type () == ObjectType . Document :
return DocumentObject . decode ( self . store . get_object_store () . get_object ( object_id ))
if object_id . get_object_type () == ObjectType . Image :
return ImageObject . decode ( self . store . get_object_store () . get_object ( object_id ))
if object_id . get_object_type () == ObjectType . Video :
return VideoObject . decode ( self . store . get_object_store () . get_object ( object_id ))
if object_id . get_object_type () == ObjectType . RichText :
return RichTextObject . decode ( self . store . get_object_store () . get_object ( object_id ))
if object_id . get_object_type () == ObjectType . Email :
return EmailObject . decode ( self . store . get_object_store () . get_object ( object_id ))
else :
pass
def parse_object_in_message ( self , message : str ) -> KnowledgeObject :
# get message's first line
logging . info ( f "tg parse resp message: { message } " )
lines = message . split ( " \n " )
if len ( lines ) > 0 :
message = lines [ 0 ]
try :
desc = json . loads ( message )
if isinstance ( desc , dict ):
object_id = desc [ "id" ]
else :
object_id = desc [ 0 ][ "id" ]
except Exception as e :
return None
if object_id is not None :
return self . load_object ( ObjectID . from_base58 ( object_id ))
def bytes_from_object ( self , object : KnowledgeObject ) -> bytes :
if object . get_object_type () == ObjectType . Image :
image_object = object
return self . get_chunk_reader () . read_chunk_list_to_single_bytes ( image_object . get_chunk_list ())