diff --git a/.env b/.env index 5882604..d15234a 100644 --- a/.env +++ b/.env @@ -2,4 +2,5 @@ POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres POSTGRES_HOST=127.0.0.1 POSTGRES_PORT=5432 -POSTGRES_DB=pretor \ No newline at end of file +POSTGRES_DB=pretor +SECRET_KEY=114514 \ No newline at end of file diff --git a/README.md b/README.md index e69de29..1679181 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,28 @@ +
+ +# Pretor (执政官) + +一款基于 Python 的分布式多 Agent 协作系统 + +[![Python 3.13+](https://img.shields.io/badge/python-3.13+-blue.svg)](https://www.python.org/) +[![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE) + +
+ +--- +**Pretor** 是一款基于 **Ray** 构建的下一代分布式多 Agent 协作系统。项目采用“中心监管 + 边缘执行”的异构集群模式,通过大参数 MoE 模型进行高层逻辑推理,并协同微调后的轻量化模型高效完成具体任务。借助 **Pydantic-AI** 提供的强类型约束与 FastAPI 异步网关,Pretor 实现了任务从需求拆解、资源调度到自动化执行的全链路闭环,为个人提供可靠的人工智能助手服务。 + +--- +## 特别之处? + +- 本项目通过 **Ray** 和 **vllm** 实现个人个性化助手的创建,你可以通过收集符合你自己偏好的数据,构建独属于自己的风格的人工智能助手。 +- 本项目通过多 Agent 协作,实现比起单 Agent 系统更强的性能,从而完成更复杂的任务。 +- 本项目通过调用本地模型,从而减少对于昂贵的API使用和一定程度上的安全保护。如果你是创作者,可以通过用自己的作品去训练属于自己的模型,提高工作效率。 +- (暂未实现)本项目适配多种消息平台,实现在外可通过多种方式给 **Pretor** 下达指令完成工作。 +- (暂未实现)本项目内置 **growth_node(生长节点)** ,实现傻瓜式微调模型操作,让你的 **Pretor** 自己学会一些独特的技能。 + +那么如何拥有属于自己的**执政官**呢? + +--- +## 快速开始 +本项目正在开发中... diff --git a/docs/project.md b/docs/project.md index 6aab94c..f686e3f 100644 --- a/docs/project.md +++ b/docs/project.md @@ -9,7 +9,7 @@ - [ ] 实现由监管模型理解并发布,子个体向下布置任务,完成任务向上传递,监管模型检查的全工作流 --- #### 简介 -**ArchonBot**是一款python开发,实现将小模型进行微调后整理为一个大型集群,从而实现低算力情况下高复杂度任务的实现。 +**Pretor**是一款python开发,实现将小模型进行微调后整理为一个大型集群,从而实现低算力情况下高复杂度任务的实现。 系统模型分为以下部分: - **监管节点**:负责基本交流和任务分流; - **管控节点**:负责调度系统资源; diff --git a/pretor/api/auth.py b/pretor/api/auth.py index ca25797..1e4560f 100644 --- a/pretor/api/auth.py +++ b/pretor/api/auth.py @@ -15,6 +15,7 @@ from fastapi import APIRouter, Request from pydantic import BaseModel from pretor.utils.access import Accessor +from fastapi.concurrency import run_in_threadpool auth_router = APIRouter(prefix="/api/v1/auth", tags=["auth"]) @@ -25,7 +26,7 @@ class UserRegister(BaseModel): @auth_router.post("/register") async def create_user(user_register: UserRegister, request: Request): postgres_database = request.app.state.postgres_database - hashed_password = Accessor.hash_password(user_register.password) + hashed_password = await run_in_threadpool(Accessor.hash_password, user_register.password) user = await postgres_database.auth_database.add_user.remote(user_register.user_name, hashed_password) return {"message": "success", "user_id": user.user_id} @@ -36,9 +37,9 @@ class UserLogin(BaseModel): @auth_router.post("/login") async def login_user(user_login: UserLogin, request: Request): postgres_database = request.app.state.postgres_database - user = postgres_database.auth_database.login_user.remote(user_login.user_name) + user = await postgres_database.auth_database.login_user.remote(user_login.user_name) if user.user_name != user_login.user_name: pass - token = Accessor.login_hashed_password(user, user_login.password) + token = await run_in_threadpool(Accessor.login_hashed_password, user, user_login.password) return {"message":"success", "token":token} diff --git a/pretor/core/global_state_machine/global_state_machine.py b/pretor/core/global_state_machine/global_state_machine.py index ca59e45..3c292e4 100644 --- a/pretor/core/global_state_machine/global_state_machine.py +++ b/pretor/core/global_state_machine/global_state_machine.py @@ -40,7 +40,7 @@ class GlobalStateMachine: del self.event_dict[event_id] def get_event(self, event_id: str) -> PretorEvent: - return self.event_dict.get("event_id", None) + return self.event_dict.get(event_id, None) def update_attachment(self, event_id: str, attachment: Dict[str, str]) -> None: self.event_dict[event_id].attachment = attachment @@ -83,10 +83,10 @@ class GlobalStateMachine: provider_apikey=provider_apikey, provider_owner=provider_owner) try: - if provider_type not in self.global_provider_manager.provider_mapper.keys(): + provider_class = self.global_provider_manager.provider_mapper.get(provider_type, None) + if provider_class is None: logger.warning(f"Provider type {provider_type} is not supported.") return None - provider_class = self.global_provider_manager.provider_mapper.get(provider_type) provider: Provider = await provider_class.create_model(provider_args) provider.provider_owner = provider_owner diff --git a/pretor/core/workflow/workflow_runner.py b/pretor/core/workflow/workflow_runner.py index 0176ea5..f0bc8d0 100644 --- a/pretor/core/workflow/workflow_runner.py +++ b/pretor/core/workflow/workflow_runner.py @@ -19,10 +19,10 @@ from loguru import logger from typing import Optional, Dict, Union, Any, List from pretor.utils.error import WorkflowError, WorkflowExit from pretor.core.individual.control_node.template import ForWorkflowInput as ControlForWorkflowInput, \ - ControlNodeResponse, ForWorkflow as ControlForWorkflow + ForWorkflow as ControlForWorkflow from pretor.core.individual.consciousness_node.template import ForWorkflowInput as ConsciousnessForWorkflowInput, \ ForSupervisoryInput, ForSupervisoryNode, ForWorkflow as ConsciousnessForWorkflow -from pretor.core.individual.supervisory_node.template import TerminationMessage, ForUser +from pretor.core.individual.supervisory_node.template import TerminationMessage class WorkflowEngine: diff --git a/pretor/core/workflow/workflow_template_manager.py b/pretor/core/workflow/workflow_template_manager.py index 602da48..9a870af 100644 --- a/pretor/core/workflow/workflow_template_manager.py +++ b/pretor/core/workflow/workflow_template_manager.py @@ -39,5 +39,5 @@ class WorkflowManager: def generate_workflow_template(self, name: str, desc: str, steps: list) -> None: try: self.workflow_template_generator.generate_workflow_template(name=name, desc=desc, steps=steps) - except: - pass \ No newline at end of file + except Exception as e: + logger.exception("Failed to generate workflow template") \ No newline at end of file diff --git a/pretor/utils/access.py b/pretor/utils/access.py index e6b44bb..f31d432 100644 --- a/pretor/utils/access.py +++ b/pretor/utils/access.py @@ -27,7 +27,7 @@ class TokenData(BaseModel): exp: Optional[int] = None -SECRET_KEY = os.getenv("SECRET_KEY", "your-fallback-secret-for-dev") +SECRET_KEY = os.getenv("SECRET_KEY") ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = 60 * 24 # 默认有效期 1 天 pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")