change /knowledge commands in shell
This commit is contained in:
@@ -1,9 +1,11 @@
|
||||
|
||||
import logging
|
||||
import toml
|
||||
import os
|
||||
import runpy
|
||||
from typing import Any, Callable, Dict, List, Optional, Union
|
||||
|
||||
from aios_kernel import AIAgent,AIAgentTemplete,AIStorage
|
||||
from aios_kernel import AIAgent,AIAgentTemplete,AIStorage,Environment
|
||||
from package_manager import PackageEnv,PackageEnvManager,PackageMediaInfo,PackageInstallTask
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -105,6 +107,18 @@ class AgentManager:
|
||||
config_data = await config_file.read()
|
||||
config = toml.loads(config_data)
|
||||
result_agent = AIAgent()
|
||||
|
||||
if "owner_env" in config:
|
||||
owner_env = config["owner_env"]
|
||||
_, ext = os.path.splitext(owner_env)
|
||||
if ext == ".py":
|
||||
env_path = os.path.join(agent_media.full_path, owner_env)
|
||||
owner_env = runpy.run_path(env_path)["init"]()
|
||||
config["owner_env"] = owner_env
|
||||
else:
|
||||
owner_env = Environment.get_env_by_id(config["owner_env"])
|
||||
config["owner_env"] = owner_env
|
||||
|
||||
if result_agent.load_from_config(config) is False:
|
||||
logger.error(f"load agent from {agent_media} failed!")
|
||||
return None
|
||||
|
||||
@@ -30,16 +30,19 @@ class KnowledgeDirSource:
|
||||
return await f.read()
|
||||
|
||||
async def next(self):
|
||||
journals = self.env.journal.latest_journals(1)
|
||||
from_time = 0
|
||||
if len(journals) == 1:
|
||||
latest_journal = journals[0]
|
||||
if latest_journal.is_finish():
|
||||
yield None
|
||||
from_time = os.path.getctime(latest_journal.get_input())
|
||||
if os.path.getmtime(self.path()) <= from_time:
|
||||
yield (None, None)
|
||||
while True:
|
||||
journals = self.env.journal.latest_journals(1)
|
||||
from_time = 0
|
||||
if len(journals) == 1:
|
||||
latest_journal = journals[0]
|
||||
if latest_journal.is_finish():
|
||||
yield None
|
||||
continue
|
||||
from_time = os.path.getctime(latest_journal.get_input())
|
||||
if os.path.getmtime(self.path()) <= from_time:
|
||||
yield (None, None)
|
||||
continue
|
||||
|
||||
file_pathes = sorted(os.listdir(self.path()), key=lambda x: os.path.getctime(os.path.join(self.path(), x)))
|
||||
for rel_path in file_pathes:
|
||||
file_path = os.path.join(self.path(), rel_path)
|
||||
|
||||
@@ -4,7 +4,17 @@ import toml
|
||||
import asyncio
|
||||
from knowledge import KnowledgePipelineEnvironment, KnowledgePipeline
|
||||
|
||||
|
||||
class KnowledgePipelineManager:
|
||||
@classmethod
|
||||
def initial(cls, root_dir: str):
|
||||
cls._instance = KnowledgePipelineManager(root_dir)
|
||||
return cls._instance
|
||||
|
||||
@classmethod
|
||||
def get_instance(cls):
|
||||
return cls._instance
|
||||
|
||||
def __init__(self, root_dir: str):
|
||||
self.root_dir = root_dir
|
||||
self.input_modules = {}
|
||||
@@ -32,7 +42,7 @@ class KnowledgePipelineManager:
|
||||
input_module = config["input"]["module"]
|
||||
_, ext = os.path.splitext(input_module)
|
||||
if ext == ".py":
|
||||
input_module = os.path.abspath(path, input_module)
|
||||
input_module = os.path.join(path, input_module)
|
||||
input_init = runpy.run_path(input_module)["init"]
|
||||
else:
|
||||
input_init = self.input_modules.get(input_module)
|
||||
@@ -41,7 +51,7 @@ class KnowledgePipelineManager:
|
||||
parser_module = config["parser"]["module"]
|
||||
_, ext = os.path.splitext(parser_module)
|
||||
if ext == ".py":
|
||||
parser_module = os.path.abspath(path, parser_module)
|
||||
parser_module = os.path.join(path, parser_module)
|
||||
parser_init = runpy.run_path(parser_module)["init"]
|
||||
else:
|
||||
parser_init = self.parser_modules.get(parser_module)
|
||||
@@ -54,6 +64,12 @@ class KnowledgePipelineManager:
|
||||
self.pipelines["names"][name] = pipeline
|
||||
self.pipelines["running"].append(pipeline)
|
||||
|
||||
def get_pipelines(self) -> [KnowledgePipeline]:
|
||||
return self.pipelines["running"]
|
||||
|
||||
def get_pipeline(self, name: str) -> KnowledgePipeline:
|
||||
return self.pipelines["names"].get(name)
|
||||
|
||||
async def run(self):
|
||||
while True:
|
||||
for pipeline in self.pipelines["running"]:
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
|
||||
class KnowledgeEnvironment(Environment):
|
||||
def __init__(self, env_id: str) -> None:
|
||||
super().__init__(env_id)
|
||||
|
||||
query_param = {
|
||||
"tokens": "key words to query",
|
||||
"types": "prefered knowledge types, one or more of [text, image]",
|
||||
"index": "index of query result"
|
||||
}
|
||||
self.add_ai_function(SimpleAIFunction("query_knowledge",
|
||||
"vector query content from local knowledge base",
|
||||
self._query,
|
||||
query_param))
|
||||
async def query_objects(self, tokens: str, types: list[str], topk: int) -> [ObjectID]:
|
||||
texts = []
|
||||
if "text" in types:
|
||||
vector = await self.compute_kernel.do_text_embedding(tokens, self._default_text_model)
|
||||
texts = await self.store.get_vector_store(self._default_text_model).query(vector, topk)
|
||||
images = []
|
||||
if "image" in types:
|
||||
vector = await self.compute_kernel.do_text_embedding(tokens, self._default_image_model)
|
||||
images = await self.store.get_vector_store(self._default_image_model).query(vector, topk)
|
||||
return texts + images
|
||||
|
||||
|
||||
def tokens_from_objects(self, object_ids: [ObjectID]) -> list[str]:
|
||||
results = dict()
|
||||
for object_id in object_ids:
|
||||
parents = self.store.get_relation_store().get_related_root_objects(object_id)
|
||||
# last parent is the root object
|
||||
root_object_id = parents[0] if parents else object_id
|
||||
logging.info(f"object_id: {str(object_id)} root_object_id: {str(root_object_id)}")
|
||||
if str(root_object_id) in results:
|
||||
results[str(root_object_id)].append(object_id)
|
||||
else:
|
||||
results[str(root_object_id)] = [root_object_id, object_id]
|
||||
content = ""
|
||||
result_desc = []
|
||||
for result in results.values():
|
||||
# first element in result is the root object
|
||||
root_object_id = result[0]
|
||||
if root_object_id.get_object_type() == ObjectType.Email:
|
||||
email = self.load_object(root_object_id)
|
||||
desc = email.get_desc()
|
||||
desc["type"] = "email"
|
||||
desc["contents"] = []
|
||||
result_desc.append(desc)
|
||||
upper_list = desc["contents"]
|
||||
result = result[1:]
|
||||
else:
|
||||
upper_list = result_desc
|
||||
|
||||
for object_id in result:
|
||||
if object_id.get_object_type() == ObjectType.Chunk:
|
||||
upper_list.append({"type": "text", "content": self.store.get_chunk_reader().get_chunk(object_id).read().decode("utf-8")})
|
||||
if object_id.get_object_type() == ObjectType.Image:
|
||||
# image = self.load_object(object_id)
|
||||
desc = dict()
|
||||
desc["id"] = str(object_id)
|
||||
desc["type"] = "image"
|
||||
upper_list.append(desc)
|
||||
if object_id.get_object_type() == ObjectType.Video:
|
||||
video = self.load_object(object_id)
|
||||
desc = video.get_desc()
|
||||
desc["type"] = "video"
|
||||
upper_list.append(desc)
|
||||
else:
|
||||
pass
|
||||
content += json.dumps(result_desc)
|
||||
content += ".\n"
|
||||
|
||||
return content
|
||||
|
||||
async def _query(self, tokens: str, types: list[str] = ["text"], index: str=0):
|
||||
index = int(index)
|
||||
object_ids = await KnowledgeBase().query_objects(tokens, types, 4)
|
||||
if len(object_ids) <= index:
|
||||
return "*** I have no more information for your reference.\n"
|
||||
else:
|
||||
content = "*** I have provided the following known information for your reference with json format:\n"
|
||||
return content + KnowledgeBase().tokens_from_objects(object_ids[index:index+1])
|
||||
Reference in New Issue
Block a user